无法从集合视图正确传递模型?

时间:2011-09-13 23:06:24

标签: backbone.js

我已经盯着这一段时间并尝试各种调整,但无济于事。

为什么我在

处收到“this.model is undefined”错误
$(function(){


  window.Sentence = Backbone.Model.extend({ 

    initialize: function() {
      console.log(this.toJSON()) 
    }
  });

  window.Text = Backbone.Collection.extend({
    model : Sentence,

    initialize: function(models, options){
      this.url = options.url;
    }
  });

  window.SentenceView = Backbone.View.extend({
    initialize : function(){
      _.bindAll(this, 'render');
      this.template = _.template($('#sentence_template').html());
    },

    render : function(){
      var rendered = this.template(this.model.toJSON());
      $(this.el).html(rendered);
      return this;
    }
  })

  window.TextView = Backbone.View.extend({
    el : $('#notebook') ,

    initialize : function(){
      _.bindAll(this, 'render');
    },

    render : function(){
      this.collection.each(function(sentence){
        if (sentence === undefined){
          console.log('sentence was undefined');
        };

        var view = new SentenceView({model: sentence});
        this.$('ol#sentences').append(view.render().el);
      });

      return this;
    }
  });

  function Notebook(params){
    this.text = new Text(
      // models
      {}, 
      // params
      {
        url: params.url 
      }
    );


    this.start = function(){
      this.text.fetch();
      this.textView = new TextView({
        collection: this.text
      });
      $('body').append(this.textView.render().el);
    };
  }

  window.notebook = new Notebook(
    { 'url': 'js/mandarin.js' }
  );

  window.notebook.start();

})

有一个在线版本,您可以在控制台中看到错误:

http://lotsofwords.org/languages/chinese/notebook/

整个回购时间是:

https://github.com/amundo/notebook/

违规行似乎位于:

https://github.com/amundo/notebook/blob/master/js/notebook.js#L31

我发现这令人困惑,因为据我所知,TextView.render中的迭代具有正确的_.each语法,我只是无法弄清楚为什么Sentence模型不是他们应该出现。

4 个答案:

答案 0 :(得分:1)

var view = new SentenceView({model: sentence});

我很确定当您将数据传递给骨干视图构造函数时,数据会添加到Backbone.View.options属性中。

更改此行

var rendered = this.template(this.model.toJSON());

到这个

var rendered = this.template(this.options.model.toJSON());

看看它是否有效

<强>更新

来自doco:

创建新视图时,您传递的选项将作为this.options附加到视图中,以供将来参考。有几个特殊选项,如果通过,将直接附加到视图:model,collection,el,id,className和tagName

因此,忽略上述建议 - 模型应默认直接附加到对象

调试时要检查的事项:

  • render()方法中确认this实际上是SentenceView对象

  • 确认您未在此处传递未定义的句子:

    var view = new SentenceView({model: sentence});
    

UPDATE2:

看起来这个集合是borked:

this.textView = new TextView({
    collection: this.text
});

要进一步调试它,您需要检查它并找出正在发生的事情。当我查看萤火虫时,收集属性对我来说不合适。

你也可能有时间问题。我认为fetch是异步的,所以你可能不希望将它集合到TextView,直到你确定它已经完成。

答案 1 :(得分:0)

Backbone surface underscore.js为您提供集合方法,以便您可以执行此操作。看看这是否适合你:

this.collection.each(function(sentence) {
  // YOUR CODE HERE
});

答案 2 :(得分:0)

我认为问题出现在下面显示的notebook.js的第48行:

render : function(){
    _(this.collection).each(function(sentence){
    var view = new SentenceView({model: sentence});
    this.$('ol#sentences').append(view.render().el);
}); 

问题是你正在包装集合,而你没有必要。将其更改为

this.collection.each(function(sentence){ ...

希望能解决它

编辑: 好的,我现在要在你的一条评论中提到时间安排时再采取其他措施

看看你在哪里取钱并将其更改为:

this.start = function(){
    this.text.fetch({
        success: _.bind( function() {
            this.textView = new TextView({
                collection: this.text
            });
            $('body').append(this.textView.render().el);
        }, this)
    );
}; 

我手动输入,因此可能存在不匹配的括号。关键是fetch是异步的。

希望这可以解决它

答案 3 :(得分:-2)

尝试使用_.each

 _.each(this.collection, function(sentence){
    if (sentence === undefined){
      console.log('sentence was undefined');
    };

    var view = new SentenceView({model: sentence});
    this.$('ol#sentences').append(view.render().el);
  },this);