There are a couple of advantages to using a function to define your view model.(使用函数定义视图模型有两个优点。)
The main advantage is that you have immediate access to a value of this
that equals the instance being created.(主要优点是您可以立即访问this
值, this
值等于正在创建的实例。) This means that you can do:(这意味着您可以执行以下操作:)
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);
};
So, your computed observable can be bound to the appropriate value of this
, even if called from a different scope.(因此,即使从其他范围调用,您的计算得到的observable也可以绑定到this
的适当值。)
With an object literal, you would have to do:(使用对象文字,您将必须执行以下操作:)
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
In that case, you could use viewModel
directly in the computed observable, but it does get evaluated immediate (by default) so you could not define it within the object literal, as viewModel
is not defined until after the object literal closed.(在那种情况下,您可以直接在计算的observable中使用viewModel
,但是它会立即进行评估(默认情况下),因此您无法在对象文字中定义它,因为viewModel
直到对象文字关闭后才定义。) Many people don't like that the creation of your view model is not encapsulated into one call.(许多人不喜欢将视图模型的创建未封装到一个调用中。)
Another pattern that you can use to ensure that this
is always appropriate is to set a variable in the function equal to the appropriate value of this
and use it instead.(你可以用它来确保另一种模式this
始终是合适的是设置在函数的变量等于适当的值this
并使用它来代替。) This would be like:(就像:)
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
Now, if you are in the scope of an individual item and call $root.removeItem
, the value of this
will actually be the data being bound at that level (which would be the item).(现在,如果你是在一个单独的项目的范围,并调用$root.removeItem
,价值this
实际上将数据在这一水平(这将是该项目)的约束。) By using self in this case, you can ensure that it is being removed from the overall view model.(通过在这种情况下使用self,可以确保将其从整体视图模型中删除。)
Another option is using bind
, which is supported by modern browsers and added by KO, if it is not supported.(另一种选择是使用bind
,如果现代的浏览器不支持,则由现代浏览器支持并由KO添加。) In that case, it would look like:(在这种情况下,它将看起来像:)
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
There is much more that could be said on this topic and many patterns that you could explore (like module pattern and revealing module pattern), but basically using a function gives you more flexibility and control over how the object gets created and the ability to reference variables that are private to the instance.(关于该主题还有更多可以说的内容,您可以探索许多模式(例如模块模式和显示模块模式),但是基本上使用函数可以为您提供更大的灵活性,并控制对象的创建方式和引用能力实例专用的变量。) 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…