2012-11-18 86 views
10

我是新來knockout.js,我試圖綁定到代表用戶的下列對象:Knockout.js:綁定到複雜的對象

{ 
    "$id": "1", 
    "$values": [ 
     { 
      "$id": "2", 
      "Locations": { 
       "$id": "3", 
       "$values": [] 
      }, 
      "Photos": { 
       "$id": "4", 
       "$values": [] 
      }, 
      "UserId": 1, 
      "Name": "Test User" 
     } 
    ] 
} 

用戶可以零個或多個位置,以及零個或更多照片。

視圖模型:

function UsersViewModel() { 
    var self = this; 
    self.users = ko.observableArray(); 

    var baseUri = 'http://localhost:46241/api/users'; 

    $.getJSON(baseUri, function (data) { 
     self.users = data; 
    }); 
} 

$(document).ready(function() { 
    ko.applyBindings(new UsersViewModel()); 
}) 

HTML中包含以下綁定:

<ul id="update-users" data-bind="foreach: users"> 
    <li> 
      <div><div class="item">User ID</div> 
       <input type="text" data-bind="value: $data.UserId" /> 
      </div>     
      <div><div class="item">Name</div> 
       <input type="text" data-bind="value: $data.Name" /> 
      </div>     
    </li> 
</ul> 

難道我不當平掉這樣做呢?或者,用戶對位置和照片的對象引用可能會搞亂綁定?

+0

用戶標識和名稱來在對象的「$ values」部分之下 - 你不包含在你的綁定中。 $值以$開頭的事實可能會讓你陷入淘汰賽的困境。如果你能夠控制物體的生成方式,那麼擺脫美元來清理它是值得的。 –

+0

是你的self.users =數據工作正常嗎?我沒有看到將$ values數組寫入您的可觀察數組 – ryadavilli

回答

17

我是不是這樣做不正確?

是的。您在JSON回調覆蓋你observableArray,從而破壞了它:

$.getJSON(baseUri, function (data) { 
    self.users = data; 
}); 

在一般情況下,淘汰賽觀測被分配到這樣的:

$.getJSON(baseUri, function (data) { 
    self.users(data.$values); 
}); 

注意,在你的情況,data.$values似乎包含實際的陣列,而不是data本身。

這將適用於您的情況,但它並沒有使用淘汰賽充分發揮其潛力。

mapping plugin已經創建完成這種情況。它遞歸地遍歷一個複雜的對象,並將其所有屬性變爲可觀察對象,並將所有包含的數組轉換爲可觀察數組。這使您可以精確控制對象的狀態,從而可以監視每個更改。

$.getJSON(baseUri, function (data) { 
    ko.mapping.fromJS(data.$values, {}, self.users); 
}); 

它還允許部分更新:假設您從服務器檢索用戶列表,並且您的視圖模型已經有一半。映射插件只能將那些缺失的視圖模型添加到視圖模型中,並對現有模型進行適當的更改。如果你想知道如何閱讀文檔中的"Advanced usage" section


假設你從服務器獲取用戶對象的數組,並使用映射插件,那麼你的結合應該是這樣的:

<ul id="update-users" data-bind="foreach: users"> 
    <li> 
      <div><div class="item">User ID</div> 
       <input type="text" data-bind="value: UserId" /> 
      </div>     
      <div><div class="item">Name</div> 
       <input type="text" data-bind="value: Name" /> 
      </div> 
      <ul class="photos" data-bind="foreach: Photos.$values"> 
       <!-- ... --> 
      <ul> 
    </li> 
</ul> 

在一般筆記,@格雷格·史密斯的評論是正確的。嘗試在對象鍵中丟失$,他們可能會在某些時候與特殊變量在淘汰賽中發生衝突。例如,您可以安全地將它們替換爲下劃線。

在更廣泛的注意,我想嘗試在你的JSON剝離出整個$id/$values想法,如果我是你,它似乎沒有任何目的:

[ 
    { 
     "Locations": [], 
     "Photos": [], 
     "UserId": 1, 
     "Name": "Test User" 
    } 
] 
+0

+1在Knockout JS的崩潰過程中 – ryadavilli

+0

謝謝,這確實有助於很多。我將檢查映射插件,該插件看起來要做很多繁重的工作。至於json的格式,這是由JSON.NET從Entity Framework對象生成的。我將如何去除$ id/$值格式? – verbose

+0

@verbose我不知道,但這是另一個問題的好材料。甚至以前沒有人問過這個問題。 – Tomalak