2012-04-07 65 views
0

所以我從那個看起來像服務器接收JSON:在創建一個knockout.js型HAS_ONE關係

{ 
    data: [ 
    { 
     foo: "hello", 
     bar_id: "92934848202" 
    }, 
    { 
     foo: "hello again", 
     bar_id: "39393020201" 
    }, 
    ] 
} 

我讀它到名爲self.data使用映射插件像observableArray :

self.data(ko.mapping.fromJS(json).data()); 

我有另一個叫bar的模塊,它從服務器讀入所有的bar和它們的id。我有一個bar中的方法,它能夠用find方法返回一個對象。所以

bar.find("39393020201") // returns object 

但我真的很想做的是有在self.data observableArray能夠直接訪問吧,做一樣的東西:

self.data()[0].bar // ideally returns object? 

我一直在最接近能夠得到到目前爲止是添加這樣的自定義函數:

ko.observable.fn.bar = function() { 
    return bar.find(this()); 
}; 

但這requries,我稱之爲

self.data()[0].bar_id.bar 

這不是很漂亮。但是,我添加到observableArray的任何函數都在整個數組上運行,而不是該數組中的特定對象。還有其他建議嗎?

回答

1

您需要分解映射過程並手動添加一個可觀察的「bar」 - 映射插件允許用計算的observable來替換bar_id(或任何其他)可觀察值,該可觀察值可以做任何您想要的操作,但是您不能創建數據對象中不存在的屬性(如「bar」)。

var tmp = []; 

for (var i = 0; i < json.data.length; i++) { 
    // Map only one object in the json.data array 
    var o = ko.mapping.fromJS(json.data[i]); 

    // Add a computed observable that turns bar_id into bar 
    o.bar = ko.computed(function() { 
     return self.bar.find(o.bar_id()); 
    }); 

    tmp.push(o); 
} 

self.data(tmp); 

http://jsfiddle.net/hTYy3/2/

+0

感謝尼科,我希望的是乾淨的方式..也許我會叉淘汰賽,看看我可以建立一些東西。 – 2012-04-07 19:11:23