声明为对象文本的挖空视图模型与函数之间的区别

2022-08-30 01:27:16

在挖空js中,我看到视图模型声明为:

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

ko.applyBindings(viewModel );

艺术

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

ko.applyBindings(new viewModel ());

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

我确实在knockoutjs google组上找到了这个讨论,但它并没有真正给我一个满意的答案。

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

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

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

但是,如果我不这样做,那么我选择哪种风格有什么关系吗?


答案 1

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

主要优点是您可以立即访问等于正在创建的实例的值。这意味着您可以执行以下操作: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

对于对象文本,您必须执行以下操作:

var viewModel = {
   first: ko.observable("Bob"),
   last: ko.observable("Smith"),
};

viewModel.full = ko.computed(function() {
   return this.first() + " " + this.last();
}, viewModel);

在这种情况下,您可以直接在计算的可观察量中使用,但它确实会立即得到评估(默认情况下),因此您无法在对象文本中定义它,因为在对象文本关闭之前不会定义它。许多人不喜欢视图模型的创建不封装到一个调用中。viewModelviewModel

可用于确保始终适用的另一种模式是在函数中设置一个等于 适当值的变量,并改用它。这就像:thisthis

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

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

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

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

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


答案 2

我使用不同的方法,尽管相似:

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

  ko.applyBindings(obj);
  return obj;
})();

几个原因:

  1. 不使用 ,在 s 等内使用时可能会造成混淆thisko.computed
  2. 我的视图模型是单例,我不需要创建多个实例(即new viewModel())