我有一個從服務返回的項目數組。我試圖爲每個Item實例定義一個計算的observable,所以我的直覺告訴我把它放在原型上。在KnockoutJS中是否可以在原型上計算observables?
計算觀察值的一種情況:系統計算點數,但用戶可以選擇覆蓋計算值。我需要保持計算值可用,以防用戶刪除覆蓋。我還需要合併用戶分配的和計算的分數,並將總計加起來。
我使用映射做到以下幾點:
var itemsViewModel;
var items = [
{ 'PointsCalculated' : 5.1 },
{ 'PointsCalculated' : 2.37, 'PointsFromUser' : 3 }
];
var mapping = {
'Items' : {
create : function(options) {
return new Item(options.data);
}
}
};
var Item = function(data) {
var item = this;
ko.mapping.fromJS(data, mapping, item);
};
Item.prototype.Points = function() {
var item = this;
return ko.computed(function() {
// PointsFromUser may be 0, so only ignore it if the value is undefined/null
return (item.PointsFromUser != null) ? item.PointsFromUser : item.PointsCalculated;
});
};
ko.mapping.fromJS(items, mapping, itemsViewModel);
現在的工作方式,我要調用匿名函數返回計算的觀測。這似乎爲每個綁定創建了一個計算可觀察值的新實例,這個實例大部分都是將其放在原型上。每次訪問可觀察數據時,要解密多少個括號纔有點煩人。
它也有點脆弱。如果我試圖接入點()的代碼,我不能做
var points = 0;
var p = item.Points;
if (p && typeof p === 'function') {
points += p();
}
因爲更改爲點()來DOMWindow的背景下,而不是項目。
如果我把計算器放在映射中的create()中,我可以捕獲上下文,但是在每個對象實例上都有一個方法的副本。
我找到Michael Best的Google Groups帖子(http://groups.google.com/group/knockoutjs/browse_thread/thread/8de9013fb7635b13)。原型在「激活」時返回一個新的計算可觀察值。我還沒有弄清楚什麼叫「激活」(也許是Objs?),但是我猜測它每個對象都會發生一次,我不知道'this'會得到什麼範圍。
在這一點上,我相信我已經超越了發佈文檔中的可用內容,但我仍在努力破譯來自源代碼的內容。
謝謝。我認爲.extend()的目的就是點擊了。這很好地解決了我的範圍/雙重函數調用問題,我會告訴你Knockout不會讓我在原型上保留實際的計算可觀察性。 – 2012-04-26 02:53:30
eric,你能否提供更多的「糖化」版本?像childClass = BaseClass.extend(function(){/*...*/}),它已經做了原型鏈設置?必須爲每個類實例手動執行它有點奇怪... – fbuchinger 2012-10-17 11:23:48
我看不出有什麼理由不能在繼承的構造函數上放置'擴展'靜態函數,只要它基本上: ' SubClass.extend = function(extender){SubClass.prototype.extend(extender); };' – ericb 2012-10-17 20:25:30