4

My view should be destroyed after the current route position is left.

So in this schematic example the login view should be destroyed after the user entered his credentials:

Routes

I tried to solve this by using Backbone.Router events:

var Router = Backbone.Router.extend({
    initialize: function () {
        Backbone.history.start();
    },
    routes: {
        "sample" : "sample"
    },
    sample: function(){
      // Build view
      var demoView = $("<div/>")
          .appendTo(document.body)  
          .text("I am lost!");

      // Destroy view
      this.once('route', function(){
        demoView.remove(); 
      });
    },
});

Unfortunately this does not work as the route events are raised after the routes are executed:

http://jsfiddle.net/hcuX9/

Is there a solution to destroy views after leaving the route position?

Do I have to hack a new event into Backbone.js?

4

3 回答 3

3

我用来做的是让一个App.current变量指向正在渲染的当前视图。

在每条路线的顶部(或您的情况下的相关路线),我从中删除当前视图App.current,然后为其分配新视图:

someRoute: function() {
  if(App.current && App.current.remove) App.current.remove();  

  // Asign a new current page
  App.current = new SomeView();
  ...
}

这样,我只让每条路线的一个视图直播,摆脱像你这样的问题。

如果您不喜欢App.current在每条路由的顶部检查和调用 remove 方法,您可以侦听 Backbone.history 路由事件并在那里注入该逻辑:

Backbone.history.on('route', function() {
  if(App.current && App.current.remove) App.current.remove();  
});
于 2013-03-31T06:41:30.053 回答
1

我认为你被你的黑客所困扰,除非你可以根据你的需要调整 .listenTo - 那么你将需要在你有路由更改的任何地方使用 .trigger 触发一个自定义事件,这可能是不可能的。请注意,之前在骨干网中已请求(并拒绝)此功能:

https://github.com/documentcloud/backbone/pull/494

查看其他试图做同样事情的补丁的拉取请求。

于 2013-03-30T13:48:53.797 回答
0

在这里,我们使用onandoff来监听传入的路由事件,而不是once因为我们不能依赖单个事件而不是当前路由。当我们收到一个即使不是我们当前路由的路由时,我们也可以销毁视图并移除监听器:

  // Destroy view
  var self = this;
  var onRoute = function(route, params){
    if(route !== 'sample'){
      demoView.remove();
      self.off('route', onRoute);
    }
  };
  this.on('route', onRoute);

我在这里修改了你的测试小提琴:http: //jsfiddle.net/rgthree/hcuX9/3/


另一种选择,因为您的小提琴(不在您的问题中)直接导航到另一个视图。这会导致在 sample2 路由之后触发其他路由的事件。因此,上述内容将删除该视图。现在,它更加完整。您可以处理它的一种更简单的方法是简单地推迟oncein a setTimeout,这样它直到当前路由被触发后才会监听:

// Destroy view
var self = this;
setTimeout(function(){        
  self.once('route', function(){
    demoView.remove(); 
  });
}, 0);

你可以在这里看到你的小提琴:http: //jsfiddle.net/rgthree/hcuX9/4/

于 2013-03-29T20:39:25.207 回答