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

时间:2012-03-06 18:09:29

标签: javascript knockout.js

在淘汰赛中,我看到View Models声明为:

var viewModel = {
    firstname: ko.observable("Bob")
};

ko.applyBindings(viewModel );

或:

var viewModel = function() {
    this.firstname= ko.observable("Bob");
};

ko.applyBindings(new viewModel ());

两者之间有什么区别?如果有的话?

我确实在knockoutjs谷歌小组找到了this discussion,但它并没有给我一个满意的答案。

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

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

var person = ... ;
ko.applyBindings(new viewModel(person));

但如果我不这样做,我选择哪种风格很重要?

2 个答案:

答案 0 :(得分:249)

使用函数定义视图模型有几个优点。

主要优点是您可以立即访问等于正在创建的实例的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);
};

因此,即使从不同的范围调用,您的计算的observable也可以绑定到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不是直到对象文字关闭后才定义。很多人不喜欢你的视图模型的创建没有被封装到一个调用中。

可用于确保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);
};

可以在这个主题和许多你可以探索的模式(比如模块模式和揭示模块模式)上说更多,但基本上使用一个函数可以让你更灵活地控制对象的创建方式和能够引用实例专用的变量。

答案 1 :(得分:12)

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

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. 中使用时可能会造成混淆
  3. 我的viewModel是一个单例,我不需要创建多个实例(即new viewModel()