延迟Backbone.sync事件

时间:2015-08-20 12:51:02

标签: jquery backbone.js jquery-deferred backbone-events

我有一个自定义的Model类,其中有一个属性可以告诉我上次获取模型的时间:

var MyModel = Backbone.Model.extend({
    fetched: null,
    fetch: function(options) {
        var self = this;
        return Backbone.Model.prototype.fetch
            .apply(this, arguments)
            .done(function(){
                self.fetched = _.now();
            });
    }
});

然后,我的View会侦听此模型的change事件并在发生这种情况时呈现自身,并根据模型是否已被提取而使用不同的结果:

var MyView = Backbone.View.extend({
    initialize: function() {
        this.listenTo(this.model, 'change', this.render);
    },
    render: function() {
        if (this.model.fetched == null) {
            // Do something
        }
        else {
            // Do something else
        }
        return this;
    }
});

我的问题是change事件在Model.fetch完成后立即触发,甚至在我设置self.fetched = _.now()之前。 我知道我此时可以手动触发事件,但这将是多余的,而且我不确定该模型在此提取过程中是否实际发生了变化。

有没有办法捕获在调用Backbone.Model.prototype.fetch期间触发的事件,以便我可以在链式done中手动触发它们?

更新:或者,有没有办法让fetch函数在触发事件之前成功运行?

2 个答案:

答案 0 :(得分:1)

计时结束是因为.done()处理程序在稍后的事件线程中触发,类似于setTimeout()

  

有没有办法捕获在调用Backbone.Model.prototype.fetch期间触发的事件,以便我可以在链接完成时手动触发它们?

不是,我希望,不要破坏Backbone,你真的不想这样做。但是,您可以利用Backbone的触发和聆听自定义事件的能力。

例如,您可以拥有一个自定义fetched事件,该事件由MyModel.fetch()中的.done()回调触发,并在您喜欢的任何地方收听。

您的MyModel.model.fetched时间戳的需求将会消失,因为与change不同,自定义事件只会从该地点触发。

var MyModel = Backbone.Model.extend({
    fetch: function(options) {
        var self = this;
        return Backbone.Model.prototype.fetch
            .apply(this, arguments)
            .done(function() {
                self.trigger('fetched');
            });
    }
});

虽然文档仅讨论与.on()相关的自定义事件,但同样可以使用.listenTo()收听它们。并且没有什么可以阻止您收听标准change以及自定义fetched事件。

这个策略允许(例如)你的“做某事”和“做别的事”在不同的监听器中执行,而不是作为单个监听器的分支执行:

var MyView = Backbone.View.extend({
    initialize: function() {
        this.listenTo(this.model, 'change', this.render_on_change);
        this.listenTo(this.model, 'fetched', this.render_on_fetch);
    },
    render_on_change: function() {
        /* Do something */
    },
    render_on_fetch: function() {
        /* Do something else */
    }
});

变化无穷无尽。你可能需要玩它,直到你得到适合你的应用程序。

为了介绍this.listenTo(this.model, 'fetched', ...);,我担心你必须咬紧牙关并对需要回应该事件的每个视图进行更改。这是不可避免的。

从积极的方面来说,任何目前拥有this.listenTo(this.model, 'change', ...);并且不需要收听fetched的模型都可以保持原样。

答案 1 :(得分:0)

您可以为获取功能提供成功回调,您可以摆脱模型中的代码。



var MyView = Backbone.View.extend({
    initialize: function() {
        var self=this
        this.listenTo(this.model, 'change', this.render);
        this.model.fetch({
            success: function(){
               self.model.fetched= _.now();
        })
    },
    render: function() {
        if (this.model.fetched == null) {
            // Do something
        }
        else {
            // Do something else
        }
        return this;
    }
});