"variable is not a function" 读取剔除变量时出错

"variable is not a function" error while reading knockout variable

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

首先让我解释一下整体结构。

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

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

还有另一个 class 派生自我的基础 class 并且在这个派生的 class.

中声明了一个名为 accNumberComputed 的计算变量
 femaleUserViewModel  = Class.create(userViewModel , {
        accNumberComputed : ko.pureComputed({
                read: function () {
                   return this.accNumber();     
                },
                write: function (value) {
                    this.accNumber(value);
                },
                owner: this
        })
});

我想根据 accNumber 可观察变量更新 accNumberComputed 变量。因此,将在 accNumberComputed 变量上跟踪对 accNumber 变量的任何修改。

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

能否请教一下这个问题

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

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

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

我快速浏览了文档,确实看到了一种类似于它在 "plain javascript approach" 中的工作方式。它是这样工作的:

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

这个:

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

变为:

var userViewModel = Class.create(baseViewModel, {
  initialize: function() {
    this.accNumber = ko.observable("");
  }
});
  1. 在扩展 class' 构造函数中显式调用基础 class' 构造函数。

不确定这是否是最好的方法,但可以像这样完成:

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>