【问题标题】:Fetch models as needed in Backbone Collection?在 Backbone Collection 中根据需要获取模型?
【发布时间】:2014-08-28 22:52:09
【问题描述】:

我想要类似以下行为:

  1. 对集合调用 get()。
  2. 仅在尚未获取模型时获取模型。
  3. 返回模型或触发事件,表明它已准备就绪。

在主干中有标准的方法吗?

【问题讨论】:

  • “标准”方式是覆盖您要为其定义不同行为的方法,在本例中为集合上的 get 方法。因此,如果我理解正确,您想在集合上调用 get ,并且如果在内部,该方法在当前集合中找不到模型,则从数据源中获取它并将其添加到集合中?跨度>
  • 没错。如果骨干已经提供了这种行为,我不会重新发明轮子,这就是我要问的。
  • AFAIK 如果不覆盖集合 get 方法,您将无法管理它。另外,您必须注意异步模型 fetch 和同步 get 行为。
  • 简而言之,没有编写自定义获取的标准方法可以做到这一点。 @Evgeniy 对 fetch 的异步性质提出了一个很好的观点,这使得在我看来,在 get 操作中使用它是有问题的。为什么不先获取一个集合然后从那里开始呢?如果有很多模型,那么分页是处理大型数据集的标准方法。

标签: javascript backbone.js backbone.js-collections


【解决方案1】:

主干中没有标准方法可以做到这一点,需要您修改模型和集合。我知道你没有在问题中提到 jQuery,我只是在我提供的延迟对象功能的示例中使用它,并且可以换出任何延迟对象库。

这种方法的问题是集合get() 方法必须返回一个延迟对象供您使用,而不是模型。这是在集合get() 方法中构建异步操作的不幸产物。

对于模型,我们需要一种方法来跟踪它是否被获取。为此使用时间戳可能允许您“超时”模型并在它已过期时重新获取它。为此,我们覆盖模型上的 fetch 方法。

警告:此代码未经测试,但提供了解决此问题的方法

var Model = Backbone.Model.extend({

    /**
     * Last fetched public variable
     * @var {Object} Date || null
     */
    lastFetched : null,


    /**
     * Custom fetch always adds a timestamp to the model
     * when it was last fetched from the server. This
     * allows us to prevent unnecessary calls to the backend
     * when a model is still fresh.
     * @return {Object} jQuery deferred
     */
    fetch : function() {

        if ( _.isNull(this.lastFetched) ) {
            this.lastFetched = new Date().getTime();

            return Backbone.Model.prototype.fetch.apply(this, arguments);
        } else {
            return new $.Deferred().resolve();
        }
    }
});

集合需要重写它的 get 方法以包含模型获取例程。 get 方法不会返回模型,而是返回一个延迟对象,该对象可用于在模型准备好时链接回调。

var Collection = Backbone.Collection.extend({

    model : Model,

    /**
     * Custom get retrieves a model if it exists and returns the result
     * of the models custom fetch method
     * @param {Integer} id | cid
     * @return {Object}
     */
    get : function(id) {
        var model = Backbone.Collection.prototype.get.apply(this, args);

        if ( ! model )
            model = new this.model({id : id});

        return {
            deferred : model.fetch(),
            model : model
        };
    }
});

用法

var collection = new Collection(),
    result = collection.get(1);

result.deferred.done(function() {
    console.log(result.model);
});

这将允许您使用您在问题中提供的工作流程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2011-07-03
    • 1970-01-01
    相关资源
    最近更新 更多