在淘汰赛 js 中,我看到视图模型声明为:
var viewModel = { firstname: ko.observable("Bob") }; ko.applyBindings(viewModel );
或者:
var viewModel = function() { this.firstname= ko.observable("Bob"); }; ko.applyBindings(new viewModel ());
如果有的话,两者有什么区别?
我确实在 knockoutjs google group 上找到了这个讨论,但它并没有真正给我一个满意的答案。
如果我想用一些数据初始化模型,我可以看到一个原因,例如:
var viewModel = function(person) { this.firstname= ko.observable(person.firstname); }; var person = ... ; ko.applyBindings(new viewModel(person));
但如果我不这样做,我选择哪种风格重要吗?
使用函数来定义视图模型有几个优点。
主要优点是您可以立即访问this等于正在创建的实例的值。这意味着您可以执行以下操作:
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因此,即使从不同的范围调用,您计算的 observable 也可以绑定到 的适当值。
使用对象文字,您必须执行以下操作:
var viewModel = { first: ko.observable("Bob"), last: ko.observable("Smith"), }; viewModel.full = ko.computed(function() { return this.first() + " " + this.last(); }, viewModel);
在这种情况下,您可以viewModel直接在计算的 observable 中使用,但它会立即评估(默认情况下),因此您无法在对象文字中定义它,因为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,您可以确保将其从整体视图模型中删除。
$root.removeItem
另一个选项是 using bind,现代浏览器支持并由 KO 添加(如果不支持)。在这种情况下,它看起来像:
bind
var ViewModel = function() { this.items = ko.observableArray(); this.removeItem = function(item) { this.items.remove(item); }.bind(this); };
关于这个主题还有更多可以说的内容以及您可以探索的许多模式(例如模块模式和显示模块模式),但基本上使用函数可以让您更灵活地控制对象的创建方式和引用能力实例私有的变量。