0

我有一个基本的 Backbone 应用程序,它从远程服务获取 JSON 对象数组并显示它们:到目前为止一切都很好。但是,每个 JSON 对象都有一个标签数组,我想在网页的单独区域中显示标签。

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

另一种方法是在主视图中收集标签信息,因为它正在通过数组工作,然后将其传递给辅助视图,但随后我将视图链接在一起。

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

代码片段的奖励积分。

4

1 回答 1

0

嗯。我不确定这是否是 Backbone 友好的方式,但我会将逻辑用于检索集合中的标签列表(我认为这就是您所说的“解析”)。

主视图和子视图都会“监听”同一个集合,而子视图只会调用 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 端点。(即使是总共 1000 个标签的 500 条数据,对于现在的现代浏览器来说也不应该太多。)

唔。这有帮助吗?

JSFiddle 与这个集合和模型一起使用:http: //jsfiddle.net/dashk/G8LaB/(并且,一个日志语句来演示结果.getTags())。

于 2013-02-12T15:05:25.500 回答