敲除视图之间的差异声明为对象文字与函数的模型
在淘汰赛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; })();
几个原因:
- 不使用
this
,在ko.computed
等使用时会混淆 - 我的viewModel是一个单身人士,我不需要创build多个实例(即
new viewModel()
)