"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" 中的工作方式。它是这样工作的:
- 不要将 observable 和 computed 添加到原型中,而是在构造函数中创建它们。 (
initialize
在 prototypejs 中)
这个:
var userViewModel = Class.create(baseViewModel , {
accNumber: ko.observable("")
});
变为:
var userViewModel = Class.create(baseViewModel, {
initialize: function() {
this.accNumber = ko.observable("");
}
});
- 在扩展 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>
我在我的网络项目中使用了 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" 中的工作方式。它是这样工作的:
- 不要将 observable 和 computed 添加到原型中,而是在构造函数中创建它们。 (
initialize
在 prototypejs 中)
这个:
var userViewModel = Class.create(baseViewModel , {
accNumber: ko.observable("")
});
变为:
var userViewModel = Class.create(baseViewModel, {
initialize: function() {
this.accNumber = ko.observable("");
}
});
- 在扩展 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>