Backbone.js模型与视图SET

时间:2012-04-19 12:57:04

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

如果我使用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});
  }
});

OR

// 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({})逻辑感觉很脏。

思想?

4 个答案:

答案 0 :(得分: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. 
      ........
  }
});

答案 1 :(得分:1)

可能会感觉很脏,因为您习惯于区分视图控制器。但是,在Backbone.js中,它不存在 - 视图也是控制器。 当你明白这一点时,与模特的互动在眼睛上变得更容易......

在我看来,解决问题的正确方法是您引入的方法的组合。保留SomeModel.toggle,并在您的视图中执行:

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

答案 2 :(得分:0)

您似乎正在将视图逻辑混合到您的模型中,这并不是一个好主意。我可以想象模型中的一些数据,这些数据与绑定它的视图是否应该是可见的(类似于删除: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});

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

答案 3 :(得分:0)

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

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