我来从服务后面项目的数组。 我试图定义一个计算的观察到的,每一个项目的实例,所以我的直觉告诉我,把它的原型。
为计算观察到的一个案例:在系统计算点,但用户可以选择替换的计算值。 我需要保持现有的计算值的情况下,用户删除覆盖。 我还需要凝聚用户分配和计算的点,加起来的总数。
我使用映射做到以下几点:
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,而不是项目。
如果我把计算的创建()的映射,我可以捕捉范围内,但随后有方法对每个对象实例的副本。
我发现麦可思的谷歌网上论坛帖子( http://groups.google.com/group/knockoutjs/browse_thread/thread/8de9013fb7635b13 )。 原型返回“激活”的新计算观察到的。 我还没有想出什么叫“激活”(也许OBJ文件?),但我猜它仍然发生每个对象一次,我没有什么线索范围“这个”将得到。
在这一点上,我相信,我过去有什么在发布的文件可用,但我仍然工作到破译什么是从源头回事。
你提到你不想拥有的实例ko.computed
在你的JavaScript类的每个实例功能,但是,不会真的有多么KO的功能已经建成运行。 当您使用ko.computed
或ko.observable
他们创建特定内存指针里面,你通常不会想跨类实例共享的私有变量(尽管在极少数情况下,你可能)。
我做这样的事情:
var Base = function(){
var extenders = [];
this.extend = function(extender){
extenders.push(extender);
};
this.init = function(){
var self = this; // capture the class that inherits off of the 'Base' class
ko.utils.arrayForEach(extenders, function(extender){
// call each extender with the correct context to ensure all
// inheriting classes have the same functionality added by the extender
extender.call( self );
});
};
};
var MyInheritedClass = function(){
// whatever functionality you need
this.init(); // make sure this gets called
};
// add the custom base class
MyInheritedClass.prototype = new Base();
然后计算的观测(这必须是在你的每一个实例实例功能MyInheritedClass
)我刚刚宣布他们在extender
像这样:
MyInheritedClass.prototype.extend(function(){
// custom functionality that i want for each class
this.something = ko.computed(function() {
return 'test';
});
});
鉴于你的榜样和Base
上面定义的类,你可以很容易做到:
var Item = function(data) {
var item = this;
ko.mapping.fromJS(data, mapping, item);
this.init(); // make sure this gets called
};
Item.prototype = new Base();
Item.prototype.extend(function () {
var self = this;
this.Points = ko.computed(function () {
// PointsFromUser may be 0, so only ignore it if the value is undefined/null
return (self.PointsFromUser != null) ?
self.PointsFromUser : self.PointsCalculated;
});
};
那么你的所有实例Item
类会有一个Points
属性,它会正确处理ko.computed
每个实例的逻辑。
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;
});
};
Item.prototype.extend(function () {
var scope = this
this.Points = ko.computed(function () {
return (this.PointsFromUser != null) ?
this.PointsFromUser : this.PointsCalculated;
}, scope);
};