2

我将 Backbone 与 RequireJS 一起使用,我的视图需要在对应于各自 RESTful API 的 20 个集合之间切换。

“正常”的方式可以很好地处理事情,除了需要为每个 API 定义一个新的 Collection 之外,这会导致代码库非常臃肿:

收集(x 20 次)

define(function(require) {
    var Backbone = require('backbone');

    var c = Backbone.Collection.extend({
        url: '/path/to/api-1'
    });

    return new c();
});

看法

define(function(require) {
    var Backbone = require('backbone'),
           c1 = require('./collections/collection-1'),
           ...
           c20 = require('./collections/collection-20');

    var v = Backbone.View.extend({
        /* Some methods to toggle between Collections here */
    });

    return v;
});

通过只return c;在 Collection 内部执行,并在 View 内部调用new c({url: /path/to/api-1});,我能够减少高度重复的 Collection 定义;但现在在每次new c();调用时,API 总是会被戳以检索新的数据副本,这是对资源的浪费,也是我不想要的。

有什么方法可以让 Collections “持久化”?哪个更好地满足以下所有标准:

  • 每个API对应的Collection,只new执行一次;
  • 每个集合都可以在使用 RequireJS 定义的不同视图之间共享/访问;
  • Collection的定义可以被所有API重用;
  • 全局命名空间根本没有被污染。
4

3 回答 3

0

您无需创建新文件/集合。

你可以在你的视图中做这样的事情:

var collections = [];
collections.push( Backbone.Collection.extend({url: '/path/to/api-1'});
collections.push( Backbone.Collection.extend({url: '/path/to/api-2'});
collections.push( Backbone.Collection.extend({url: '/path/to/api-3'});

...

collections.push( Backbone.Collection.extend({url: '/path/to/api-20'});

var view1 = Backbone.View.extend( {data:collections} );
var view2 = Backbone.View.extend( {data:collections} );

然后,您将加载一个包含所有集合的数组

于 2012-08-31T22:20:31.807 回答
0

与另一个答案类似,您可以将集合数组定义为 AMD 模块:

收藏品

define(['backbone', 'underscore'], function(Backbone, _) {
    var collections = [];

    var urls = ['/path/to/api-1', '/path/to/api-2', '/path/to/api-3'];

    _(urls).each(function(url) {
        collections.push(Backbone.Collection.extend({
            url: url
        }));
    });

    return collections;
});

你的观点可以像这样使用它:

看法

define(['Backbone', 'collections'], function(Backbone, collections) {

    var v = Backbone.View.extend({
        /* Some methods to toggle between Collections here */
    });

    return v;
});
于 2012-09-02T16:35:30.760 回答
0

找到了一个相当hackish的解决方案:

用另一个Model包装你的Collection

define(function(require) {
    var Backbone = require('backbone'),
        m = require('../models/model');

    var wrapper = Backbone.Model.extend({
        initialize: function() {
            var $_path = this.get('path');

            var c = Backbone.Collection.extend({
                model: m,

                url: $_path,

                initialize: function() {
                    this.deferred = this.fetch();
                }
            });

            this.set({
                collection: new c()
            });
        }
    });

    return wrapper;
});

然后,定义一个 Cache 容器:

define(function(require) {
    return cache = {};
});

在 View 模块中需要 Cache 容器和包装的 Collection:

define(function(require) {
    var $ = require('jquery'),
        _ = require('underscore'),
        Backbone = require('backbone'),
        cache = require(cache),
        wrapper = require('../collections/collection');

    var v = Backbone.View.extend({
        render: function($_path) {
            var c = cache[$_path] || cache[$_path] = new wrapper({
                path: $_path
            }).get('collection'));
        } 
        ....
    });

    return v;
});

通过这种方式,您可以获得使用动态生成的值实例化新集合的好处$_path,并且能够缓存从您的 API 获取的数据,只要页面不刷新 -localStorage如果您希望数据在页面刷新时保持不变,请实施。

于 2012-09-03T04:03:56.413 回答