首页 文章

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

提问于
浏览
191

在淘汰赛中,我看到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 回答

  • 12

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

    主要优点是您可以立即访问 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);
    };
    

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

  • 249

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

    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是一个单例,我不需要创建多个实例(即 new viewModel()

相关问题