2012-08-17 119 views
0

我有这个工作正常的骨干,我只是想渲染集合被抓取!如何使用主干渲染集合?

代码:

var SearchView = Backbone.View.extend({ 
     events: { 
      "keyup": "handleChange" 
     }, 
     initialize: function(){ 
      this.collection.bind("reset", this.updateView, this); 
     }, 
     render: function(){ 
      // this is where i need help 
      this.$el.next('#suggestions').append(// iterate over this.collection and apppend here) // 

     }, 
     handleChange: function(){ 
      var term = this.$el.val(); 
      this.collection.search(term); 
     }, 

     updateView: function() { 

      this.render(); 
     } 

    }); 

我只是想遍历this.collection并显示“文本”属性,这就是每个集合内,其追加到(“#suggestions”)EL。感谢

回答

1

专注于你的重置,呈现了收藏的问题,这是我会怎么做。这种方式假定当你创建你的视图时,$ el已经存在,并且你通过View构造函数传递它,所以它已经准备好了。

var SearchView = Backbone.View.extend({ 
     template: _.template('<span><%= term %></span>'); 
     initialize: function(){ 
      this.collection.bind("reset", this.render, this); 
     }, 
     render: function(){ 
      this.addAllTerms(); 
      return this; 
     }, 
     addAllTerms: function() { 
      var self = this; 
      this.collection.each(function(model) { 
       self.addTerm(model); 
      }); 
     }, 
     addTerm: function(someModel) { 
      this.$el.next('#suggestions').append(this.template(someModel.toJSON())); 
     } 
    }); 

这与您的方法在几个方面有点不同。首先,我们利用Underscore的模板功能。这可能是从span到li到div的任何东西。我们使用<%=%>来表示我们要插入一些值(它将来自我们的model.term属性)。

而不是去处理程序然后渲染,我只是绑定集合呈现。

render()假设我们总是要刷新整个事情,从头开始构建。 addAllTerms()只需循环收集。您可以使用forEach()或只是each()这是除了forEach()是一样的东西是3个字符太懒了我的懒惰流氓。 ;-)

最后,addTerm()函数采用一个模型并将其用于它将附加到#suggestions的值。基本上,我们说“用插值附加模板”。我们将上面的模板函数定义为此View对象属性,以清楚地将模板与数据分开。虽然你可以跳过这部分,但只是append('<span>' + someModel.get('term') + '</span>')或什么不是。 _.template()使用我们的模板,并且还使用与我们模板中的属性对齐的属性的任何类型的对象。在这种情况下,'期限'。

这只是一个不同的方式来做你正在做的事情。我认为这段代码更易于管理。例如,也许你想添加一个新术语而不刷新整个集合。 addTerm()函数可以独立运行。

编辑:

并不重要,但有些事我的模板使用,我发现有用的,我没有看到它,当我第一次开始了。当你传递model.toJSON()到模板功能,我们基本上是通过所有的模型属性中所以,如果该模型是这样的:

defaults: { 
    term: 'someTerm', 
    timestamp: '12345' 
} 

在我们前面的例子中,该属性时间戳也传递不使用,只使用<%= term %>。但是我们也可以通过将它添加到模板中来轻松插入它。我想知道的是,您不必限制自己从一个模型中获取数据。一个复杂的模板可能有几个模型的数据。

我不知道这是最好的方式,但我做的是有这样的事情:

makeHash: function() { 
    var hash = {}; 
    hash.term = this.model.get('term'); 
    hash.category = anotherModel.get('category'); 

    var date = new Date(); 
    hash.dateAccessed = date.getTime(); 

    return hash; 
} 

所以,你可以轻松地构建自己的自定义哈希扔成模板,聚集所有的您想要将数据插入到要传递到模板中的单个对象中。

// Instead of .toJSON() we just pass in the `makeHash()` function that returns 
// a customized data object 

this.$el.next('#suggestions').append(this.template(this.makeHash())); 

您还可以轻松地传入整个对象。

makeHash: function() { 
    var hash = {}; 
    hash.term = this.model.get('term'); 

    var animal = { 
     name: 'aardvark', 
     numLegs: 4 
    }; 

    hash.animal = animal; 

    return hash; 
} 

并通入我们的模板看起来像这样的:

template: _.template('<span><%= term %></span> 
    <span><%= animal.name %></span> 
    <span><%= animal.numLegs %></span>') 

我不知道这是否是最好的方式,但它让我了解到什么数据进入我的模板。也许很明显,但当我刚开始时,这不适合我。

0

我找到了解决问题的办法,我也会把它放在这里,可能想知道的人:

render: function(){ 
      this.collection.forEach(function(item){ 
       alert(item.get("text")); 
      }); 
     }