Backbone.Marionette扩展区域停止onClose()函数调用

时间:2014-08-12 11:56:37

标签: javascript backbone.js marionette

我已创建了Backbone,Marionette和Require.js应用程序,现在我正尝试在区域之间添加平滑过渡。

要轻松做到这一点*我决定扩展牵线木偶代码,以便它可以在我的所有页面上工作(因为很多页面因此手动操作会太多)

我扩展了marionette.region的开启和关闭功能。问题是它现在没有在我的每个视图中调用onClose函数。

如果我将代码直接添加到牵线木偶文件中,它可以正常工作。所以我可能错误地合并了这些功能,对吧?

这是我的代码:

extendMarrionette: function () {
  _.extend(Marionette.Region.prototype, {

    open : function (view) {
      var that = this;

      // if this is the main content and should transition
      if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === true) {
        this.$el.empty().append(view.el);
        $(document).trigger("WrapperContentChanged")

      } else if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === false) {
        $(document).on("WrapperIsHidden:open", function () {

          //swap content
          that.$el.empty().append(view.el);

          //tell router to transition in
          $(document).trigger("WrapperContentChanged");

          //remove this event listener
          $(document).off("WrapperIsHidden:open", that);
        });

      } else {
        this.$el.empty().append(view.el);
      }

    },

    //A new function Ive added - was originally inside the close function below. Now the close function calls this function.
    kill : function (that) {
      var view = this.currentView;
      $(document).off("WrapperIsHidden:close", that)
      if (!view || view.isClosed) {
        return;
      }

      // call 'close' or 'remove', depending on which is found
      if (view.close) {
        view.close();
      }
      else if (view.remove) {
        view.remove();
      }

      Marionette.triggerMethod.call(that, "close", view);

      delete this.currentView;
    },

    // Close the current view, if there is one. If there is no
    // current view, it does nothing and returns immediately.
    close : function () {
      var view = this.currentView;
      var that = this;

      if (!view || view.isClosed) {
        return;
      }

      if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === true) {
        this.kill(this);

      } else if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === false) {

        //Browser bug fix - needs set time out
        setTimeout(function () {
          $(document).on("WrapperIsHidden:close", that.kill(that));
        }, 10)


      } else {
        this.kill(this);
      }

    }

  });
}

2 个答案:

答案 0 :(得分:1)

为什么不延长Marionette.Region?这样,您可以选择使用自定义Region类,如果您不需要在所有情况下平滑过渡,则可以选择原始类。 (如果某些特定情况需要某些特定行为,您可以再次扩展它。)

https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md#region-class

var MyRegion = Marionette.Region.extend({
    open: function() {
        //Your open function
    }

    kill: function() {
        //Your kill function
    }

    close: function() {
        //Your close function
    }
});

App.addRegions({
    navigationRegion: MyRegion
});

答案 1 :(得分:0)

也许你的问题是你没有将函数传递给你的事件监听器,而是直接在下面的代码中调用代码。

setTimeout(function(){
  $(document).on("WrapperIsHidden:close", that.kill(that));
}, 10)

你可能想要这样的东西:

setTimeout(function(){
  $(document).on("WrapperIsHidden:close", function (){ that.kill(that); });
}, 10)

另一个可能的问题是,您在this函数中混淆了对that / kill的引用。您可能希望在整个方法中将var view分配给that.view或使用this而不是that

回答您的其他问题:

您应该尝试将view函数中的close变量直接传递到kill函数,因为当您使用currentView时对kill的引用已更改为新视图对象实际上想要旧视图对象。发生这种情况的原因是您在执行show功能之前设置了超时。如果查看close源代码,可以看到这一点。它希望opencurrentView和{{1}}分配按顺序同步发生。