2012-04-07 64 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