将mixin与ko.computed一起添加到knockout viewmodel中

时间:2015-01-19 12:45:49

标签: javascript knockout.js mixins

阅读本文后:A fresh look at javascript mixins我想将一些常见的淘汰计算函数移到mixin中,并将其混合到需要该功能的每个viewmodel中。

首先是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);

我的问题似乎是这个(或者自我在viewmodel中设置为 this )指向windows对象而不是视图模型。有任何想法吗? Javascript mixins对我来说是新的,所以我可能会遗漏一些明显的东西。

3 个答案:

答案 0 :(得分:2)

asActor.call(SenderActor.prototype);执行以下操作 -

  1. 调用asActor并将SenderActor.protototype对象作为this
  2. 传递
  3. this.nrOfEmployees = ko.computed(...)SenderActor.protototype
  4. 内创建了一个ko.computed
  5. 它评估在同一上下文中计算的this仍然指向SenderActor.protototype
  6. 根据您employees或其原型链中是否包含SenderActor.protototype,此代码会产生或不会产生错误。

    现在我假设这种行为不是你想要的。

    尝试在SenderActor构造函数中运行asActor.call(this);

答案 1 :(得分:1)

当你通过一个函数创建新对象时,比如new asActor(),会有一个默认值为你返回 - 魔术"这个"。只需运行一个函数,就必须添加一个return语句。

我已经测试了您的代码,它没有任何问题但运行asActor没有返回值。

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;
};

答案 2 :(得分:1)

正如奥尔加所说,在原型上创建计算机本身并不是我的意图。我选择的解决方案是使用Base类:

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);
        });
    };
};

在生成代码中,我在所有viewmodel构造函数中添加了 this.Init()调用

最后,我在每个viewmodel上调用.extend函数,将这些函数混合在一起:

SenderActor.prototype.extend(asActor);
ReceiverActor.prototype.extend(asActor);