我重新组织了可以正常工作的Backbone.js项目,并将所有模型,集合和视图移到了单独的文件中,并做了一些重写,但现在无法渲染。我已经尝试了所有我能想到的。有小费吗?

var SessionView = Backbone.View.extend({
    model: Session,
    el: '#list',
    template:  _.template($('#session-template').html()),
    initialize: function () {
        this.model.bind('change', _.bind(this.render, this));
        this.render();
    },
    render: function () {
        this.$el.html(this.template({sessions: sessionList}));
        return this;
    }
});
var sessionView = new SessionView();

var SessionListView = Backbone.View.extend({
    el: '#list',
    model: sessionList,
    initialize: function () {
        sessionList.bind('add', this.add, this);
        sessionList.bind('reset', this.add, this);
        sessionList.fetch();
    },
    render: function () {
        var view = new sessionListView();
        this.$el.append(view.render().el);
        new SessionView({model: Session});
        return this;
    }
});

var sessionListView = new SessionListView();

最佳答案

我注意到的几件事:


Backbone.View没有模型属性。只有Backbone.Collection具有模型属性,该主干将使用指定的模型构造函数(蓝图)和传递给它的数据来创建模型实例。

但是视图没有这样的功能(据我所知)。人们通常在创建视图时传递带有选项的特定类型模型的实例,这与在View的构造函数中指定指向模型构造函数的model属性不同。

sessionList似乎不是模型的实例(因为它是在视图的构造函数中指定的。如果是实例,则它将由所有SessionListView实例共享,这在大多数情况下都不是所需的行为)似乎是undefined

在以下内容中:new SessionView({model: Session}); Session看起来不像是模型的实例(不是以大写字母开头,希望您遵循命名约定),并且似乎也是undefined

没什么能阻止您在视图的构造函数中指定模型构造函数或将模型构造函数传递到视图中,但是您应该在视图内部创建它的一个实例(通常是在初始化时)。换句话说,您不能执行blueprintOfAModel.bind('change'..);,而应该为视图创建一个实际的模型。
您似乎正在使用SessionListViewrender本身的SessionListView方法中创建新的var view = new sessionListView();,当您只是尝试创建一个实例时,不会创建无限数量的SessionListView实例。

好了,通过再次查看它,您并不是在使用SessionListView运算符调用实际的构造函数new,而是使用了一个可能引发错误的实例(sessionListView)。
SessionViewSessionListView都指向相同的元素,这似乎很奇怪。我从未见过有人这样做,因为修改一个视图的el会影响另一视图,这在大多数实际情况下都是不希望的。

同样根据名称进行判断,因为您具有会话的列表视图,所以SessionView不应使用id选择器指向特定元素。您应该为每个SessionView实例创建一个新元素。如果您不指定el属性,Backbone将为您完成此操作。


(我想说您稍加重写就创建了一个意外混乱:)



从某种意义上讲,您的代码应类似于以下内容。请注意,以大写字母开头的内容是构造函数,而以小写字母开头的内容是对象实例

var Session = Backbone.Model.extend({
  defaults: {},
  initialize: function() {}
});
var SessionList = Backbone.Collection.extend({
  model: Session,
  initialize: function() {}
});
var SessionView = Backbone.View.extend({
  initialize: function() {
    this.model.bind('change', _.bind(this.render, this));
    this.render();
  },
  template: _.template($('#session-template').html()),
  render: function() {
    this.$el.html(this.template({
      session: this.model
    }));
    return this;
  }
});
var SessionListView = Backbone.View.extend({
  el: '#list',
  initialize: function() {
    this.collection.bind('add', this.add, this); // method doesn't exist, should throw error
    this.collection.bind('reset', this.add, this); // same here
    this.collection.fetch();  // <--- watch out, this happens asynchronously
  },
  render: function() {
    // iterate through collection, create instances of SessionView and append to el
    return this;
  }
});

var sessionList = new SessionList(); // will create n number of Session instances in future

var sessionListView = new SessionListView({ // will create n number of SessionView instances in future
  collection: sessionList
});

10-08 04:12