Javascript 主干JS:当导航到另一个url时,如何清理视图?

Javascript 主干JS:当导航到另一个url时,如何清理视图?,javascript,backbone.js,Javascript,Backbone.js,我有一个Homeview,它在页面上包含一些子视图,当我使用路由器导航到另一个页面时,如何清理现有视图,并为我要导航到的页面构建新视图 此应用程序没有模型/集合,只有视图 谢谢大家! 守则的一部分: Home = Backbone.View.extend({ template: "static/js/templates/home.html", initialize: function() { _.bindAll(this); this.render();

我有一个Homeview,它在页面上包含一些子视图,当我使用路由器导航到另一个页面时,如何清理现有视图,并为我要导航到的页面构建新视图

此应用程序没有模型/集合,只有视图

谢谢大家!

守则的一部分:

Home = Backbone.View.extend({
    template: "static/js/templates/home.html",

    initialize: function() {
      _.bindAll(this);
      this.render();
    },

    render: function() {
      var view = this;

      // Fetch the template, render it to the View element and call done.
      namespace.fetchTemplate(this.template, function(tmpl) {
        view.el.innerHTML=tmpl();
        view.subRender();
      });

      return this;
    },
    subRender: function() {
      var view = this;
      var videoView = new Subview1({
        el: $('#wrapper1'),
        homeView: view
      });
      var timeView = new Subview2({
        el: $("#wrapper2")
      });
    }
 });

我将子视图存储在一个数组中,当我关闭“父”视图时,通过视图的
close()
函数,迭代数组并关闭子视图

这要求子视图1和子视图2也具有
close()
函数

Home = Backbone.View.extend({
    template: "static/js/templates/home.html",

    initialize: function() {
      _.bindAll(this);
      this.render();
      // Hold sub views
      this.views = [];
    },
    close: function() {
      this.remove();
      this.unbind();
      this.clear_views();
    },
    clear_views: function() {
      while this.views.length > 0
        this.views[0].close()
        this.views.splice(0, 1)
    },
    render: function() {
      var view = this;

      // Fetch the template, render it to the View element and call done.
      namespace.fetchTemplate(this.template, function(tmpl) {
        view.el.innerHTML=tmpl();
        view.subRender();
      });

      return this;
    },
    subRender: function() {
      var view = this;
      var videoView = new Subview1({
        el: $('#wrapper1'),
        homeView: view
      });
      this.views.push(videoView);
      var timeView = new Subview2({
        el: $("#wrapper2")
      });
      this.views.push(timeView);
    }
 });

如果需要的话,您可以使用主干网的事件机制来实现这一点

您只需要创建一个全局事件路由器,然后让每个视图侦听
CloseView
事件。然后,您只需在收到
CloseView
事件时执行所有关机操作

var dispatcher = _.clone(Backbone.Events)

Home = Backbone.View.extend({
    ...
    initialize: function() {
        ...
        dispatcher.on( 'CloseView', this.close, this );
    }
    close: function() {
        // Unregister for event to stop memory leak
        dispatcher.off( 'CloseView', this.close, this );
        this.remove();
        this.unbind();
        this.views = [];   // Clear the view array
    }
    ...
});

SubView = Backbone.View.extend({
    ...
    initialize: function() {
        ...
        dispatcher.on( 'CloseView', this.close, this );
    }
    close: function() {
        // Unregister for event to stop memory leak
        dispatcher.off( 'CloseView', this.close, this );
        // Do other close stuff here.
    }
});
然后在路由器/其他地方调用
dispatcher.trigger('OnClose')
来触发关闭函数

作为一种快捷方式,假设您希望在每个导航上执行此关闭操作,您可以在路由器上注册事件(如此处所示的自定义“OnClose”事件,或仅获取每个导航的“all”事件),但您必须注意事件的调用顺序是否符合预期


可能还可以将其中一些代码重构为Backbone.View.prototype或类似的代码,但我会让其他人来做。

谢谢,顺便说一下,我们可以将close()添加到Backbone.View.prototype中。我目前正在以类似的方式进行此操作,但正在寻找一种更优雅的解决方案。我能问一下,为什么您不在每条路线上都这样做?为什么要清除视图[]?显然,view.stopListening()现在在view.remove上被自动调用-那么上面的内容仍然相关吗自定义事件方法是有意义的,但是我们现在应该以不同的方式执行关闭吗?@pushplaybang我差不多2年前写过这篇文章,所以我不记得为什么要清除视图[]。回复:每一条路线,我都提到在路由器上注册
all
事件。是的,自从我写这篇文章以来,主干已经有了一些进步——使用了
View.listenTo
View.remove
的组合。这些天来,删除
可能是正确的方法。@obmarg-非常感谢,为我澄清了很多。