【问题标题】:Backbone.Marionette: Defer view close until beforeClose animation is completeBackbone.Marionette:将视图关闭推迟到 beforeClose 动画完成
【发布时间】:2012-09-16 17:35:50
【问题描述】:

我正在尝试使用 Backbone.Marionette 设置渲染和关闭 ItemView 的动画。对于渲染视图,这相当简单:

MyItemView = Backbone.Marionette.View.extend({
   ...
   onRender: function() {
     this.$el.hide().fadeIn();
   }
   ...
});

这将使我的视图在渲染时淡入。但是,假设我想在关闭时淡出我的视图。

beforeClose: function() {
   this.$el.fadeOut();       // doesn't do anything....
}

这不起作用,因为调用this.beforeClose()后项目立即关闭,所以动画没有时间完成。

有没有什么办法,使用 Marionette 来完成结束动画?


或者,这是我一直在使用的解决方法:

_.extend(Backbone.Marionette.ItemView.prototype, {
    close: function(callback) {

        if (this.beforeClose) {

            // if beforeClose returns false, wait for beforeClose to resolve before closing
            // Before close calls `run` parameter to continue with closing element
            var dfd = $.Deferred(), run = dfd.resolve, self = this;
            if(this.beforeClose(run) === false) {
                dfd.done(function() {
                    self._closeView();              // call _closeView, making sure our context is still `this`
                });
                return true;
            }
        }

        // Run close immediately if beforeClose does not return false
        this._closeView();
    },

// The standard ItemView.close method.
    _closeView: function() {
        this.remove();

        if (this.onClose) { this.onClose(); }
        this.trigger('close');
        this.unbindAll();
        this.unbind();      
    }
});

现在我可以这样做了:

beforeClose: function(run) {
    this.$el.fadeOut(run);      // continue closing view after fadeOut is complete
    return false;
},

我刚开始使用 Marionette,所以我不确定这是否是最佳解决方案。如果这是最好的方法,我会提交一个拉取请求,不过我会想更多地思考这如何与其他类型的视图一起使用。

这可能会用于其他目的,例如在关闭时要求确认(参见issue),或运行任何类型的异步请求。

想法?

【问题讨论】:

    标签: javascript jquery backbone.js marionette


    【解决方案1】:

    重写close 方法是实现此目的的一种方法,但您可以将其写得更短一些,因为您可以调用Marionettes close 方法而不是复制它:

    _.extend(Backbone.Marionette.ItemView.prototype, {
        close: function(callback) {
            var close = Backbone.Marionette.Region.prototype.close;
            if (this.beforeClose) {
    
                // if beforeClose returns false, wait for beforeClose to resolve before closing
                // Before close calls `run` parameter to continue with closing element
                var dfd = $.Deferred(), run = dfd.resolve, self = this;
                if(this.beforeClose(run) === false) {
                    dfd.done(function() {
                        close.call(self);
                    });
                    return true;
                }
            }
    
            // Run close immediately if beforeClose does not return false
            close.call(this);
        },
    
    
    });
    

    另一个想法是覆盖视图的remove 方法。所以你淡出视图的元素,然后从 DOM 中删除它

    remove: function(){
      this.$el.fadeOut(function(){
        $(this).remove();
      }); 
    }
    

    【讨论】:

    • 啊...谢谢!我知道一定有更简单的方法,覆盖 View.remove 对我来说似乎更简单。顺便说一句,在 fadeOut 回调中,您需要调用 $(this).remove()Backbone.Marionette.ItemView.prototype.call(self)
    • 重写 remove 函数是比重写 close 方法更好的解决方案。这对我很有用。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 2020-03-26
    • 2016-03-09
    • 1970-01-01
    相关资源
    最近更新 更多