在Backbone Collection中根据需要获取模型?

时间:2014-08-27 20:50:15

标签: javascript backbone.js backbone-collections

我想要以下行为:

  1. 在集合上调用get()。
  2. 仅在尚未获取模型时获取模型。
  3. 返回模型或触发表示已准备就绪的事件。
  4. 在骨干网中是否有标准方法可以做到这一点?

1 个答案:

答案 0 :(得分: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);
});

这样您就可以使用问题中提供的工作流程。