【问题标题】:Backbone.js Model vs. View SETBackbone.js 模型与视图集
【发布时间】:2012-04-30 23:57:02
【问题描述】:

如果我使用 Backbone,其中哪一种(或两者)是设置数据的“正确”方式?

// Logic in the Model
// Can call from anywhere that has access
SomeModel = Backbone.Model.extend({
  defaults: {
    visible: false
  },

  toggle: function(visible){
    visible = typeof visible !== "undefined" ? visible : !this.get("visible");
    this.set({visible: visible});
  }
});

或

// Logic in the View
SomeView = Backbone.View.extend({
  events: {
    "click .toggle" : "toggleVisibility"
  },

  toggleVisibility: function(){
    this.model.set({visible: !this.model.get("visible")});
  }
});

显然其中任何一个都有效,但我的问题是应该将多少逻辑推到模型中?例如,如果我有更新两个变量的情况:

this.model.set({visible: false, foo: bar, something: else});

在模型上创建这样的函数是否有意义:

someFunction: function(visible, foo, something){
  this.set({visible: visible, foo: foo, something: something});
}

这对我来说似乎有点矫枉过正,但视图中的 set({}) 逻辑感觉很脏。

想法?

【问题讨论】:

    标签: javascript model-view-controller design-patterns backbone.js


    【解决方案1】:

    我会让切换函数成为模型的成员,并从您的视图中调用它,隐藏实现细节。请记住,一个模型一次可以由多个视图表示,因此任何常见的模型逻辑都应该集中在那里。

    可能是这样的:

    // Logic in the Model
    // Can call from anywhere that has access
    SomeModel = Backbone.Model.extend({
      defaults: {
        visible: false
      },
    
      toggle: function(visible){
        visible = typeof visible !== "undefined" ? visible : !this.get("visible");
        this.set({visible: visible});
      }
    });
    OR
    
    // Logic in the View
    SomeView = Backbone.View.extend({
      initialize: function() {
          this.model.bind('change:visibility',this.changeVisibility);
      }
      events: {
        "click .toggle" : "toggleVisibility"
      },
    
      toggleVisibility: function(){
        this.model.toggle();
      }
      changeVisibility: function() { 
          ........
          /// seems like alot of extra work to get to this point
          /// but remember, all views for the model are will receive this
          /// event now, not just the one that received the UI click
          /// whether or not that's the behavior you want is up to you. 
          ........
      }
    });
    

    【讨论】:

      【解决方案2】:

      可能会觉得很脏,因为您已经习惯了 views 和 controllers 之间的区别。然而,在 Backbone.js 中,它并不存在 - 视图也是控制器。 当您了解这一点时,与模型的交互就会变得更加容易......

      在我看来,解决您的问题的正确方法是结合您介绍的方法。将SomeModel.toggle 留在原处,并在您看来:

          toggleVisibility: function() { this.model.toggle(); }
      

      【讨论】:

        【解决方案3】:

        您似乎将视图逻辑混合到您的模型中,这并不是一个好主意。我想在您的模型中有 一些数据与绑定它的视图是否应该可见(例如已删除:true 等)有关,但您应该根据该属性切换可见性变化。我会设想这样的事情:

        SomeModel = Backbone.Model.extend();
        
        SomeView = Backbone.View.extend({
          events: {
            "click .toggle" : "toggleDeleted"
          },
        
          initialize: function() {
              this.model.on('change:deleted', this.toggleVisibility);
          },
        
          toggleDeleted: function() {
            var deleted = this.model.get('deleted');
            this.model.set({deleted: !deleted});
          },
        
          toggleVisibility: function(){
            this.$el.toggle(); // jQuery function toggling visibility
          }
        });
        
        // Somewhere in your "controller" logic
        var someModel = new SomeModel({deleted: false});
        var someView = new SomeView({model: someModel, el: DOMelement});
        

        这样,您的所有视图逻辑都在您的视图中,而不是您的模型中。该模型是空的,因为主干不需要定义模式,但通常您会在某个时候在那里添加功能。

        【讨论】:

          【解决方案4】:

          类似的问题,有一个很好的答案,在这里:Should views set model data?

          与大多数之前的评论者一样,一般的答案似乎是:如果您要更改显示元素,请在视图中设置数据。如果您要设置业务逻辑,请在模型中设置数据。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-10-31
            • 1970-01-01
            • 2013-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-11
            • 1970-01-01
            相关资源
            最近更新 更多