使用函数定义视图模型有几个优点。
主要的优点是您可以立即访问一个值为等于被创建实例的 this
。这意味着您可以执行:
var ViewModel = function(first, last) {
this.first = ko.observable(first);
this.last = ko.observable(last);
this.full = ko.computed(function() {
return this.first() + " " + this.last();
}, this);
};
因此,即使从不同的作用域调用,您的计算可观察对象仍可以绑定到适当的this
值。
对于对象字面量,您需要执行以下操作:
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
在这种情况下,你可以直接在计算的可观察对象中使用
viewModel
,但它会立即被评估(默认情况下),因此不能在对象字面量内部定义它,因为
viewModel
在对象字面量结束之后才被定义。许多人不喜欢将视图模型的创建分散到多个调用中。
另一种模式你可以使用来确保
this
总是适当的是,在函数中设置一个变量等于适当值的
this
,然后使用它代替。就像这样:
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
如果您在个别项目的范围内调用 $root.removeItem
,那么this
的值实际上将是绑定在该级别的数据(即该项)。在这种情况下使用 self 可以确保它从整个视图模型中被移除。
另一个选择是使用 bind
,它由KO添加并得到现代浏览器的支持。在这种情况下,它看起来像:
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
在这个主题上还有很多可以说的话,也有许多模式可以探索(比如模块模式和揭示模块模式),但基本上使用函数可以给你更多的灵活性和控制对象的创建方式,以及能够引用实例私有变量的能力。
prototype
上声明(例如从服务器获取数据并相应地更新视图模型的方法)。但是你显然仍然可以将它们声明为对象字面量的属性,所以我真的看不出有什么区别。 - James Allardice