2

我试图通过尽可能避免任何请求来最小化服务器调用。

假设,举个例子,我有一组属于用户并分配了标签的火柴盒,然后还有一组标签和一组用户作为其他页面的一部分。获取 matchboxes 检索用户和标签信息,以便我可以通过一个请求实例化所有需要的模型,访问标签和用户页面检索相似的集合(只有它们只处理各自的模型)。

我的问题:如果匹配框是一个页面,而标签和用户是另外两个页面,那么确保任何给定实体仅实例化一个模型的好方法是什么,即。如果我进入用户或标签并编辑与火柴盒关联的条目,则火柴盒条目应该分配相同的条目,允许它在返回示例中的火柴盒页面时收听更新并对更新做出反应,而无需发送请求。

我已经查看了 Backbone.relational ,但它似乎并没有满足我的需要,并且宁愿不将自己限制在一个框架中。因此,涉及模式的解决方案是可取的。

4

3 回答 3

1

最终使用http://pathable.github.io/supermodel/它使用了使用自定义函数覆盖model集合上的属性的模式,该函数调用一个特殊Model.create的,它本身返回一个现有的(如果需要,用新值更新)实例模型。Model.create 调用必须用于唯一模型的代码中的其他任何地方。

所以基本上每个模型都有一个all()方法,它是所有实例的集合。每当添加模型时,它都会根据集合检查它并返回现有对象(如果存在);用于实例化副本的数据用于更新现有对象,以确保数据不会过时(这是对我想要的唯一性的一个很好的奖励)。

最简洁的方法似乎是将模型函数包装成一个返回它以便更清晰使用的函数;然后对于每个需要具有唯一模型的集合,将所述模型包装在函数中。我当时想出了这个:

app.single = function (modelPrototype) {
    return function (attrs, options) {
        return modelPrototype.create(attrs, options);
    };
};

app只有一个全局范围,绑定到特定的命名空间)

所以在集合中,而不是,

model: app.Model

然后我会使用

model: app.single(app.Model),

每当我在应用程序的某个部分更新条目时,更改都会渗透到所有其他集合/模型,因为如果从用户的角度来看它是同一个实例,那么它在代码中也是同一个实例。

这就是我通过代码和文档阅读模式所能知道的全部内容。这对我自己的用途来说已经足够了。

我怀疑如果你正在缓存渲染,这个解决方案仍然会有一些问题,但我还没有找到它的用途(尽可能地重新渲染以避免处理各种工件),所以这对我来说都是好事。

不幸的是,代码库似乎被部分放弃了,所以虽然它适用于 Backbone 1.0.0(就独特的模型而言),但我可能需要在未来的项目中重新创建/分叉该模式。

于 2013-08-06T12:04:25.707 回答
0

我认为你应该三思而后行以这种方式嵌套你的模型和集合,特别是如果它主要是为了简化你的应用程序的引导。相反,尽量使用 id 在模型之间进行相互引用。如果您现在以某种方式构建模型/集合树,那么您遇到的这个设计问题很可能只是众多问题中的第一个,但后来发现它太不灵活了。

话虽如此,如果您只需要引用其他模型/集合的模型能够引用相同的模型/集合实例,那么只需在引导期间实例化它们并将它们传递给它们各自的父模型就足够了。您可以在一个请求中加载一些引导数据,或者最好在 HTML 中内联该数据:

<script>
var bs_data = {
    users : [
        ...
    ],
    tags : [
        ...
    ],
    matchboxes : [
        ...
    ]
};
</script>

然后使用引导数据实例化相应的模型或集合。

var matchboxes = new Matchboxes();
matchboxes.set(bs_data.matchboxes);

var users = new Users({matchboxes:matchboxes});
users.set(bs_data.users);

引导数据将来自同一个后端,因此您的模型和集合已经同步,而无需获取任何内容。

至于设计模式;将依赖项作为构造函数参数传递实际上是依赖项注入模式,尽管存在更自动化的解决方案。

于 2013-08-06T10:37:53.373 回答
0

为了确保只有一个模型被实例化,并且在使用它的其他元素之间共享,能够在任何元素对其进行更改时进行侦听和更新,您可以使用单例模式。你可以在这里阅读更多关于它的信息

如果你使用 Requirejs,如果你总是返回实例化的模型,你可以获得相同的效果。例如:

// the shared model
define([
  'jquery',
  'underscore',
  'backbone'
], function ($, _, Backbone) {
  'use strict';

  var Model = Backbone.Model.extend({

    // ...

  });
  // return instantiated, so we'll get the same object back whenever we use this model (singleton)
  return new Model();

});

// a view using the model
define([
  'jquery',
  'underscore',
  'backbone',
  'model'
], function ($, _, Backbone, modelInstance) {
  'use strict';

  var View = Backbone.View.extend({
    initialize: function () {
        // listen to what other elements do
        this.listenTo(modelInstance, 'eventFromOtherElement', this.doSomething);
        // when this element does something, other elements should be listening to that event
        modelInstance.trigger('thisViewEvent');
    },
    doSomething: function () {
        // ...
    }
  });
  return View;
});
于 2013-08-06T10:49:20.480 回答