2013-02-12 69 views
0

我有一个基本的Backbone应用程序,它从远程服务获取JSON对象数组并显示它们:迄今为止都是很好的。但是,每个JSON对象都有一个标签数组,我想在网页的单独区域中显示标签。在Backbone.js中处理子视图

我的问题是:做这件事最友好的方式是什么?我可以在第二个视图中再次解析现有数据,该视图更清晰,但需要更多计算(处理整个数组两次)。

另一种方法是在主视图中收集标记信息,因为它正在处理数组,然后将它传递给子视图,但随后将视图链接在一起。

最后,我想根据这些标签进行过滤(因此标签会变成切换按钮,打开/关闭这些按钮将过滤主视图中的信息);这对于如何布置这有什么不同?

代码片段的加分。

回答

1

嗯。我不确定这是否是对骨干友好的方式,但是我会把这个逻辑放在集合中检索一个标签列表(我认为这就是你的意思是“解析”)。

主视图和子视图都将“侦听”相同的集合,子视图只会调用collection.getTags()来获取它需要的标记列表。

// Model that represents the list data 
var ListDataModel = Backbone.Model.extend({ 
    defaults: function() { 
     return { 
      name: null, 
      tags: [] 
     }; 
    } 
}); 

// Collection of list data 
var ListDataCollection = Backbone.Collection.extend({ 
    model: ListDataModel, 
    initialize: function() { 
     var me = this; 

     // Expires tag collection on reset/change 
     this.on('reset', this.expireTagCache, this); 
     this.on('change', this.expireTagCache, this); 
    }, 
    /** 
    * Expires tag cache 
    * @private 
    */ 
    expireTagCache: function() { 
     this._cachedTags = null; 
    }, 
    /** 
    * Retrieves an array of tags in collection 
    * 
    * @return {Array} 
    */ 
    getTags: function() { 
     if (this._cachedTags === null) { 
      this._cachedTags = _.union.apply(this, this.pluck('tags')); 
     } 

     return this._cachedTags; 
    }, 

    sync: function(method, model, options) { 
     if (method === 'read') { 
      var me = this; 

      // Make an XHR request to get data for this demo 
      Backbone.ajax({ 
       url: '/echo/json/', 
       method: 'POST', 
       data: { 
        // Feed mock data into JSFiddle's mock XHR response 
        json: JSON.stringify([ 
         { id: 1, name: 'one', tags: [ 'number', 'first', 'odd' ] }, 
         { id: 2, name: 'two', tags: [ 'number', 'even' ] }, 
         { id: 3, name: 'a', tags: [ 'alphabet', 'first' ] } 
        ]), 
       }, 
       success: function(resp) { 
        options.success(me, resp, options); 
       }, 
       error: function() { 
        if (options.error) { 
         options.error(); 
        } 
       } 
      }); 
     } 
     else { 
      // Call the default sync method for other sync method 
      Backbone.Collection.prototype.sync.apply(this, arguments); 
     } 
    } 
}); 

var listColl = new ListDataCollection(); 
listColl.fetch({ 
    success: function() { 
     console.log(listColl.getTags()); 
    } 
}); 

我想两个原因收集在处理这样的:

  • 它使视图代码清洁(这是因为我们没有在标签提取做的非常复杂的逻辑 - 它只是一个简单_.pluck()和_.union()
  • 它0业务逻辑参与 - 它可以说是属于数据层

为了解决性能问题:。

  • 它确实经历了两次收集 - 但是,如果即使在这种情况下,您正在使用的数据太多,客户端也无法处理,您可能需要考虑要求后端提供API端点为了这。 (即使有500个数据总共有1000个标签,对于现代的浏览器来说也不应该太多。)

嗯。这有帮助吗?

JSF与这个集合和模型一起去:http://jsfiddle.net/dashk/G8LaB/(和一个日志语句来演示.getTags()的结果)。

+0

非常感谢。我已经稍微调整了一下,但是这给了我需要的信息,把一些东西放在一起。 – jgm 2013-02-13 10:08:13