简体   繁体   English

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

[英]Backbone.Marionette extending region stops onClose() function from calling

I've created a Backbone, Marionette and Require.js application and am now trying to add smooth transitioning between regions. 我创建了Backbone,Marionette和Require.js应用程序,现在尝试在区域之间添加平滑过渡。

To do this easily* ive decided to extend the marionette code so it works across all my pages (theres a lot of pages so doing it manually would be too much) 为了轻松做到这一点,*我决定扩展木偶代码,使其在我的所有页面上都可以使用(其他页面很多,因此手动进行操作会太多)

Im extending the marionette.region open and close function. 我扩展了marionette.region打开和关闭功能。 Problem is that it now doesnt call the onClose function inside each of my views. 问题在于它现在不在我的每个视图内调用onClose函数。

If I add the code directly to the marionette file it works fine. 如果我直接将代码添加到木偶文件中,则可以正常工作。 So I'm probably merging the functions incorrectly, right? 所以我可能不正确地合并了功能,对吗?

Here is my code: 这是我的代码:

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);
      }

    }

  });
}

Why don't you extend the Marionette.Region? 您为什么不扩展Marionette.Region? That way you can choose between using your custom Region class, or the original one if you don't need the smooth transition in all cases. 这样一来,您就可以选择使用自定义Region类,或者如果不需要在所有情况下都进行平滑过渡,则可以选择原始类。 (And you can always extend it again if you need some specific behavior for some specific case). (如果您在某些特定情况下需要某些特定行为,则可以随时再次对其进行扩展)。

https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md#region-class 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
});

Perhaps your issue is that you are not passing a function to your event listener, but instead calling the code directly in the code below. 也许您的问题是您没有将函数传递给事件侦听器,而是直接在下面的代码中调用该代码。

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

It is likely that you want something like this: 您可能想要这样的东西:

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

Another possible problem is that you are mixing up your references to this / that in your kill function. 另一个可能的问题是,你是你的推荐混合达到this / that在你kill功能。 It seems like you probably want var view to either be assigned to that.view or to use this rather than that throughout the method. 似乎您可能希望将var view分配给that.view或使用this而不是that整个方法中使用它。

Answer to your additional problems: 回答您的其他问题:

You should try passing the view variable from the close function directly into your kill function because the reference to currentView is already changed to the new view object when you actually want to old view object. 您应该尝试将close函数中的view变量直接传递到kill函数中,因为当您实际上想要旧的view对象时,对currentView的引用已经更改为新的view对象。 The reason this is happening is that you are setting a timeout before executing the kill function. 发生这种情况的原因是您在执行kill功能之前设置了超时。 You can see this if you look at the show source code. 如果查看show源代码,则可以看到此内容。 It expects close , open and then currentView assignment to happen synchronously in order. 它期望closeopen然后currentView分配按顺序同步发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM