所有 Backbone 个模型正在使用 RequireJS 初始化

All Backbone models being initialized using RequireJS

我有一个使用 requirejs 构建的 backbone/marionette 项目。

define([
  'views/FormView',
  'path/to/Model',
], function (FormView, Model) {
  "use strict";

  return FormView.extend({

    model: new Model(),

    /* --- rest of view stuff --- */

  });
});

项目中的所有模型都在页面加载时被初始化(即,将在所有模型上调用 initialize()),但视图仅在控制器实例化时才被初始化。

模型只应在实例化后初始化,这让我很头疼。

有人遇到过这个吗?

更新:

感谢 Kevin 和 Yura 的回答,此代码有效:

define([
  'views/FormView',
  'path/to/Model',
], function (FormView, Model) {
  "use strict";

  return FormView.extend({

    model: undefined,

    initialize: function () {
      this.model = new Model();
    }

    /* --- rest of view stuff --- */

  });
});

模型只应在实例化后初始化

根据定义,它们将是。

您在上面的 class 定义中实例化模型,因此它的初始化程序在定义 FormView 代码时运行。您可能想要做的是在控制器中创建视图时将模型作为选项传递,例如:

var my_model = new Model();
var my_view = new FormView({model: my_model});

你的问题是

model: new Model()

此 requirejs 模块加载到浏览器后立即运行。也就是说,当需要时,它 returns 扩展 FormView,并且该原型用于 FormView.

的所有实例

此时 Model 的新实例对象被实例化,同一个实例被用作 FormView 的每个新实例的 model 属性。

您可以做的不是直接使用 model 属性 扩展 FormView,而是将 model 实例创建委托给 FormView 的初始化] 实例:

define([
 'views/FormView',
 'path/to/Model', 
], function (FormView, Model) {   "use strict";

  return FormView.extend({

    initialize: function(){
      /* Create property `model` whenever new instance of FormView is created */
      this.model = new Model();
    }

    /* --- rest of view stuff --- */

  });
});

这里是展示差异的完整工作示例:

/** EXAMPLE 1 **
  Directly extending with `model` property and assigning 
  new instance of `Model`. Later you find out same model 
  instance is used for all `MyView` instances.
*/
var MyView = Backbone.View.extend({
  model: new Backbone.Model(),
  render: function(){
    this.$el.text('I am ' + this.model.get('name'));
  }
});

var myView1 = new MyView();
myView1.$el.appendTo(document.body);
var myView2 = new MyView();
myView2.$el.appendTo(document.body);

myView1.model.set({name: "Joe"});
myView2.model.set({name: "Bob"});

myView1.render();
myView2.render();

/** EXAMPLE 2 **
  Extending with `model` in initialize will create and assign
  new instance of `model` every time `MyOtherView` instance is created.
*/
var MyOtherView = Backbone.View.extend({
  initialize: function(){
    this.model = new Backbone.Model();
  },
  render: function(){
    this.$el.text('I am ' + this.model.get('name'));
  }
});

var myView1 = new MyOtherView();
myView1.$el.appendTo(document.body);
var myView2 = new MyOtherView();
myView2.$el.appendTo(document.body);

myView1.model.set({name: "Alice"});
myView2.model.set({name: "Catrine"});

myView1.render();
myView2.render();
<script src='http://code.jquery.com/jquery.js'></script>
<script src='http://underscorejs.org/underscore.js'></script>
<script src='http://backbonejs.org/backbone.js'></script>