2014-12-02 29 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