2014-12-02 57 views
2

我正在使用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格 - 隐藏在页面加载。我尝试设置style="display:none",然后data-bind="if:User"data-bind="if:User.Id"。设置display属性会隐藏加载时的元素,但在绑定时不会更改。

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

+0

[问题1](http://stackoverflow.com/q/13168767/390278) – 2014-12-02 17:17:56

+1

而不是总是重新绑定为什么你没有一个适当的视图模型与一个selecteduser属性,只是在automcomplete处理程序更新?使用这种方法,你可以使用'with'绑定,它也解决了你的两个问题:http://jsfiddle.net/74mvbkme/ – nemesv 2014-12-02 17:30:40

+1

你的评论看起来比我的答案我删除了我的。请添加您的评论作为答案。欢呼 – 2014-12-02 17:39:24

回答

0

而不是始终重新绑定,你需要有一个selectedUser特性适当视图模型,只是更新一个在automcomplete处理。

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