敲除视图之间的差异声明为对象文字与函数的模型

在淘汰赛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上find了这个讨论 ,但并没有给我一个满意的答案。

如果我想用一些数据初始化模型,我可以看到一个原因,例如:

 var viewModel = function(person) { this.firstname= ko.observable(person.firstname); }; var person = ... ; ko.applyBindings(new viewModel(person)); 

但是如果我不这样做,我select哪一种风格是否重要?

使用函数来定义视图模型有两个好处。

主要优点是您可以立即访问与正在创build的实例相同的值。 这意味着你可以这样做:

 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); }; 

所以,即使从不同的范围调用,你的计算观察值也可以被绑定到适当的值。

用一个对象字面值,你将不得不这样做:

 var viewModel = { first: ko.observable("Bob"), last: ko.observable("Smith"), }; viewModel.full = ko.computed(function() { return this.first() + " " + this.last(); }, viewModel); 

在这种情况下,您可以直接在计算的observable中使用viewModel ,但是它会立即执行(默认情况下),所以您不能在对象文本中定义它,因为viewModel直到对象文字closures之后viewModel定义。 许多人不喜欢你的视图模型的创build没有被封装成一个调用。

您可以使用另一个模式来确保this做总是合适的,就是在函数中设置一个variables,使其等于适当的值,然后使用它。 这将是:

 var ViewModel = function() { var self = this; this.items = ko.observableArray(); this.removeItem = function(item) { self.items.remove(item); } }; 

现在,如果您处于单个项目的范围内并调用$root.removeItem ,则其值将实际上是绑定在该级别的数据(这将是项目)。 通过在这种情况下使用self,可以确保将其从整个视图模型中删除。

另一种select是使用bind ,如果不支持,则由现代浏览器支持并由KO添加。 在这种情况下,它看起来像:

 var ViewModel = function() { this.items = ko.observableArray(); this.removeItem = function(item) { this.items.remove(item); }.bind(this); }; 

关于这个主题还有很多可以说的,你可以探索的许多模式(如模块模式和揭示模块模式),但基本上使用一个函数可以给你更多的灵活性和控制如何创build对象和引用的能力variables是实例的私有variables。

我使用了不同的方法,虽然类似:

 var viewModel = (function () { var obj = {}; obj.myVariable = ko.observable(); obj.myComputed = ko.computed(function () { return "hello" + obj.myVariable() }); ko.applyBindings(obj); return obj; })(); 

几个原因:

  1. 不使用this ,在ko.computed等使用时会混淆
  2. 我的viewModel是一个单身人士,我不需要创build多个实例(即new viewModel()