简体   繁体   English

添加带有ko.computed的mixin到淘汰模型

[英]Add mixin with ko.computed to knockout viewmodel

After reading this article: A fresh look at javascript mixins I wanted to move some common knockout computed functions to a mixin and mix that into each viewmodel that needs the functionality. 阅读本文后: 重新学习javascript mixin,我想将一些常用的剔除计算函数移至mixin并将其混合到需要该功能的每个viewmodel中。

First the mixin function 首先是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 })
};

Then the call to mix the mixin into the target objects prototype 然后调用将mixin混合到目标对象原型中

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

My problem seems to be that this (or self which is set to this inside the viewmodel) points to the windows object and not the viewmodel. 我的问题似乎是这个 (或在viewmodel内部设置为此的 self )指向Windows对象而不是viewmodel。 Any ideas? 有任何想法吗? Javascript mixins is new to me so I'm probably missing something obvious here. Javascript mixins对我来说是新手,所以我可能在这里缺少明显的东西。

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

  1. it calls asActor and passes SenderActor.protototype object as this 它调用asActor并将SenderActor.protototype对象作为this
  2. this.nrOfEmployees = ko.computed(...) creates a ko.computed inside SenderActor.protototype this.nrOfEmployees = ko.computed(...)在SenderActor.protototype内部创建一个SenderActor.protototype
  3. it evaluates the computed in same context this still points to SenderActor.protototype 它计算在计算同样的背景下this仍然指向SenderActor.protototype

Depending on whether you do or do not have employees in your SenderActor.protototype or it's chain of prototypes this code will or will not produce errors. 取决于您的SenderActor.protototype是否有employees ,或者它的原型链中,此代码是否会产生错误。

Now I am assuming this behaviour is not what you were aming at. 现在, 我假设这种行为不是您要瞄准的对象。

Try running asActor.call(this); 尝试运行asActor.call(this); inside SenderActor constructor. 在SenderActor构造函数中。

When you create new object by a function, say new asActor(), there will be a default value to return for you - the magic "this". 当您通过函数创建新对象时,例如说new asActor(),将为您返回一个默认值-魔法“ this”。 You must add a return statement when you just run a function. 仅在运行函数时必须添加return语句。

I've tested your code, it has no problems but there no return value from running asActor. 我已经测试了您的代码,它没有问题,但是从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;
};

As Olga said, creating a computed on the prototype itself was not really my intention. 正如奥尔加所说,在原型本身上创建计算机并不是我的初衷。 The solution I chose was to use a 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);
        });
    };
};

In the generation code I added this.Init() call in all viewmodel constructors . 在生成代码中,我在所有viewmodel构造函数中添加了this.Init()调用

Finally I called the .extend function on each viewmodel to have these functions mixed in: 最后,我在每个视图模型上调用了.extend函数,以将这些函数混合在一起:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM