将带有 ko.computed 的 mixin 添加到 knockout viewmodel
Add mixin with ko.computed to knockout viewmodel
读完这篇文章后:A fresh look at javascript mixins我想将一些常见的淘汰计算函数移动到一个 mixin 中,并将其混合到需要该功能的每个视图模型中。
首先是mixin函数
var asActor = function() {
this.nrOfEmployees = ko.computed(function () {
if (this.employees())
return this.employees().length;
return 0;
}, this).extend({ throttle: 20 });
this.nrOfAddresses = ko.computed(function () {
if (this.addresses())
return this.addresses().length;
return 0;
}, this).extend({ throttle: 20 })
};
然后调用将 mixin 混合到目标对象原型中
asActor.call(SenderActor.prototype);
asActor.call(ReceiverActor.prototype);
我的问题似乎是 this(或 self 设置为 this在视图模型中)指向 windows 对象而不是视图模型。有任何想法吗? Javascript mixins 对我来说是新手,所以我可能遗漏了一些明显的东西。
当您通过函数创建新对象时,例如 new asActor(),将为您提供一个默认值 return - 神奇的 "this"。当你只是 运行 一个函数时,你必须添加一个 return 语句。
我测试了你的代码,它没有问题,但是 运行ning asActor 没有 return 值。
var asActor = function() {
this.nrOfEmployees = ko.computed(function () {
if (this.employees())
return this.employees().length;
return 0;
}, this).extend({ throttle: 20 });
this.nrOfAddresses = ko.computed(function () {
if (this.addresses())
return this.addresses().length;
return 0;
}, this).extend({ throttle: 20 })
return this;
};
asActor.call(SenderActor.prototype);
执行以下操作 -
- 它调用
asActor
并将 SenderActor.protototype
对象作为 this
传递
this.nrOfEmployees = ko.computed(...)
在 SenderActor.protototype
中创建一个 ko.computed
- 它在相同的上下文中评估计算
this
仍然指向 SenderActor.protototype
根据您是否在 SenderActor.protototype
或其原型链中包含 employees
,此代码是否会产生错误。
现在我假设这种行为不是你想要的。
在 SenderActor 构造函数中尝试 运行 asActor.call(this);
。
正如 Olga 所说,在原型本身上创建计算并不是我的本意。我选择的解决方案是使用 Base class:
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);
});
};
};
在生成代码中,我在所有视图模型构造函数中添加了 this.Init() 调用。
最后,我在每个视图模型上调用了 .extend 函数,将这些函数混合在一起:
SenderActor.prototype.extend(asActor);
ReceiverActor.prototype.extend(asActor);
读完这篇文章后:A fresh look at javascript mixins我想将一些常见的淘汰计算函数移动到一个 mixin 中,并将其混合到需要该功能的每个视图模型中。
首先是mixin函数
var asActor = function() {
this.nrOfEmployees = ko.computed(function () {
if (this.employees())
return this.employees().length;
return 0;
}, this).extend({ throttle: 20 });
this.nrOfAddresses = ko.computed(function () {
if (this.addresses())
return this.addresses().length;
return 0;
}, this).extend({ throttle: 20 })
};
然后调用将 mixin 混合到目标对象原型中
asActor.call(SenderActor.prototype);
asActor.call(ReceiverActor.prototype);
我的问题似乎是 this(或 self 设置为 this在视图模型中)指向 windows 对象而不是视图模型。有任何想法吗? Javascript mixins 对我来说是新手,所以我可能遗漏了一些明显的东西。
当您通过函数创建新对象时,例如 new asActor(),将为您提供一个默认值 return - 神奇的 "this"。当你只是 运行 一个函数时,你必须添加一个 return 语句。
我测试了你的代码,它没有问题,但是 运行ning asActor 没有 return 值。
var asActor = function() {
this.nrOfEmployees = ko.computed(function () {
if (this.employees())
return this.employees().length;
return 0;
}, this).extend({ throttle: 20 });
this.nrOfAddresses = ko.computed(function () {
if (this.addresses())
return this.addresses().length;
return 0;
}, this).extend({ throttle: 20 })
return this;
};
asActor.call(SenderActor.prototype);
执行以下操作 -
- 它调用
asActor
并将SenderActor.protototype
对象作为this
传递
this.nrOfEmployees = ko.computed(...)
在SenderActor.protototype
中创建一个 ko.computed
- 它在相同的上下文中评估计算
this
仍然指向SenderActor.protototype
根据您是否在 SenderActor.protototype
或其原型链中包含 employees
,此代码是否会产生错误。
现在我假设这种行为不是你想要的。
在 SenderActor 构造函数中尝试 运行 asActor.call(this);
。
正如 Olga 所说,在原型本身上创建计算并不是我的本意。我选择的解决方案是使用 Base class:
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);
});
};
};
在生成代码中,我在所有视图模型构造函数中添加了 this.Init() 调用。
最后,我在每个视图模型上调用了 .extend 函数,将这些函数混合在一起:
SenderActor.prototype.extend(asActor);
ReceiverActor.prototype.extend(asActor);