【问题标题】:Binding problems with complex data and autocomplete复杂数据和自动完成的绑定问题
【发布时间】:2014-12-29 16:27:33
【问题描述】:

我正在使用 Knockout JS 3.2,我想将它与自动完成下拉菜单一起使用。我无法解决两个问题。

我简化了数据和代码,所以它可以独立运行:

<script type="text/javascript">
    var data = [
            { "User": { "Id": 1, "DisplayName": "john a" }, "Roles": [{ "Id": 1, "Name": "admins" }, { "Id": 2, "Name": "users" }] },
            { "User": { "Id": 2, "DisplayName": "john b" }, "Roles": [] },
            { "User": { "Id": 3, "DisplayName": "john c" }, "Roles": [{ "Id": 1, "Name": "admins" }] },
            { "User": { "Id": 4, "DisplayName": "john d" }, "Roles": [] },
            { "User": { "Id": 5, "DisplayName": "john e" }, "Roles": [{ "Id": 2, "Name": "users" }] }
    ];

    $(function () {
        $("#searchTerm").autocomplete({
            source: data,
            minLength: 1,
            select: function (event, ui) {
                if (ui.item) {
                    var viewModel = ko.mapping.fromJS(ui.item);
                    ko.cleanNode($("#userDetails")[0]);
                    ko.applyBindings(viewModel, $("#userDetails")[0]);
                }
            }
        })
        .autocomplete("instance")._renderItem = function (ul, item) {
            return $("<li>")
              .append("<a>" + item.User.DisplayName + "</a>")
              .appendTo(ul);
        };
    });
</script>


<div>Select User: <input id="searchTerm" name="searchTerm" type="text" /></div>

<div id="userDetails">
    <div>User: <span data-bind="text: User.DisplayName"></span></div>
    <div data-bind="foreach: Roles, visible: Roles().length > 0">
        <div><span data-bind="text: Name"></span></div>
    </div>
</div>

问题:

  1. 我想仅在绑定时显示userDetails div——在页面加载时隐藏它。我尝试设置style="display:none",然后设置data-bind="if:User"data-bind="if:User.Id"。设置显示属性会在加载时隐藏元素,但在绑定时不会更改。

  2. 角色元素绑定无法正常工作。第一次选择该用户时,角色会显示,但在更改用户选择后无法显示。

【问题讨论】:

  • 与其总是重新绑定,为什么不拥有一个具有 selecteduser 属性的正确视图模型,而只是在 automcomplete 处理程序中更新它?通过这种方法,您可以使用 with 绑定,它还可以解决您的两个问题:jsfiddle.net/74mvbkme
  • 你的评论看起来比我删除我的答案更贴切。请添加您的评论作为答案。欢呼
  • 您还应该使用 bindingHandler 进行自动完成(在线查找或创建自己的),而不是在文档加载时添加自动完成。

标签: javascript jquery knockout.js


【解决方案1】:

您需要拥有一个具有selectedUser 属性的正确视图模型,而不是总是重新绑定,并且只需在自动完成处理程序中更新该模型。

var viewModel = {
    selectedUser: ko.observable()
}

ko.applyBindings(viewModel, $("#userDetails")[0]);

$(function () {
    $("#searchTerm").autocomplete({
        source: data,
        minLength: 1,
        select: function (event, ui) {
            if (ui.item) {
                var user = ko.mapping.fromJS(ui.item);
                viewModel.selectedUser(user);                                       
            }
        }
    })
    .autocomplete("instance")._renderItem = function (ul, item) {
        return $("<li>")
          .append("<a>" + item.User.DisplayName + "</a>")
          .appendTo(ul);
    };
});

通过这种方法,您可以使用with binding,它也可以解决您的两个问题:

<div id="userDetails" data-bind="with: selectedUser">
    <div>User: <span data-bind="text: User.DisplayName"></span></div>
    <div data-bind="foreach: Roles, visible: Roles().length > 0">
        <div><span data-bind="text: Name"></span></div>
    </div>
</div>

演示JSFiddle.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2017-05-20
    相关资源
    最近更新 更多