"变量不是函数"读取敲除变量

时间:2016-07-08 07:47:34

标签: knockout.js prototypejs observable

我在我的网络项目中使用prototypejs和knockout。

首先让我解释整体结构。

我有一个名为userViewModel的基类,并在此类定义中声明了一个名为accNumber的可观察变量。

 userViewModel = Class.create(baseViewModel , {
        accNumber: ko.observable("")
});

还有另一个派生自我的基类的类,在这个派生类中声明了一个名为accNumberComputed的计算变量。

 femaleUserViewModel  = Class.create(userViewModel , {
        accNumberComputed : ko.pureComputed({
                read: function () {
                   return this.accNumber();     
                },
                write: function (value) {
                    this.accNumber(value);
                },
                owner: this
        })
});

我想更新accNumberComputed变量取决于accNumber observable变量。因此,将在accNumberComputed变量上跟踪对accNumber变量的任何修改。

但是任何this.accNumber()语句用法都会返回一个 " TypeError:this.accNumber不是函数"错误信息。 据我所知,必须使用函数调用运算符读取可观察变量。

请你帮我解决一下这个问题。

1 个答案:

答案 0 :(得分:0)

如果你深入挖掘一下,你会发现在你的例子中this.accNumber不仅不是函数,它实际上是undefined

计算的this方法中的read是指window

我不熟悉prototypejs库,但可能有办法让它正确绑定到实例。

我快速浏览了一下文档,确实看到了一种类似于“普通javascript方法”的工作方式。它的工作原理如下:

  1. 不要将observable和computed添加到原型中,而是在构造函数中创建它们。 (原型中的initialize
  2. 此:

     var userViewModel = Class.create(baseViewModel , {
       accNumber: ko.observable("")
     });
    

    变为:

    var userViewModel = Class.create(baseViewModel, {
      initialize: function() {
        this.accNumber = ko.observable("");
      }
    });
    
    1. 在扩展类'构造函数中显式调用基类'构造函数。
    2. 不确定这是否是最佳方式,但可以这样做:

      var Extended = Class.create(Base, {
        initialize: function() {
          Extended.superclass.prototype.initialize.call(this);
      

      在您的示例中,这是您将获得的:

      var baseViewModel = Class.create({
        initialize: function() {
          this.base = "base";
        }
      });
      
      var userViewModel = Class.create(baseViewModel, {
        initialize: function() {
          this.accNumber = ko.observable("1");
        }
      });
      
      var femaleUserViewModel = Class.create(userViewModel, {
        initialize: function() {
          femaleUserViewModel.superclass.prototype.initialize.call(this);
          
          this.accNumberComputed = ko.pureComputed({
            read: function() {
              return this.accNumber();
            },
            write: function(value) {
              this.accNumber(value);
            },
            owner: this
          })
        }
      });
      
      var janeDoe = new femaleUserViewModel();
      console.log(janeDoe.accNumberComputed());
      janeDoe.accNumberComputed(2);
      console.log(janeDoe.accNumberComputed());
      <script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>