BackboneJS - 导航和显示问题

时间:2013-12-10 10:16:17

标签: backbone.js backbone-routing

我已经设置了一个主导航菜单,其中包含4-5个锚点和相关视图。它的典型“家”,“约”,“新闻”等菜单。在其中一个视图中,让我们说“新闻”还有一个带有3个锚点的附加菜单,让我们说“国家”,“国际”和“其他”,当您点击它们时,它会在“新闻”视图中显示相关视图它应该只显示在那里。到现在为止还挺好。但是,当我点击主导航上的“关于”锚时,它会向我显示关于视图,但仍然是“新闻”视图中的附加菜单,当然我不希望这样。那么,在这做什么?

[更新] :我做了一些更改,但仍然无效!

我将backbone.view-prototype代码添加到我的mainpage.js:

define(function (require) {

'use strict';

Backbone.View.prototype.close = function(){
    this.remove();
    this.unbind();
    if (this.onClose){
        this.onClose();
    }
}

var AppRouter = require('../app/routers/router');

$(function () {

    var App = new AppRouter();

});

});

我将close函数添加到我的视图中:

define(['backbone','handlebars', 'text!templates/News.html'],



    function(Backbone,Handlebars, Template) {

        'use strict';


        var NewsView = Backbone.View.extend({

            template: Handlebars.compile(Template),

            events: {
            },

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

            render: function() {
                $(this.el).html(this.template());
                return this;
            },

            close: function(){
                this.remove();
                this.unbind();
            }

        });

        return NewsView;    

    }
 );

我的路由器看起来像这样(短版):

        var Router = Backbone.Router.extend({

        routes: {
            '': 'index',
            'pages/about' : 'about',
            'pages/news' : 'news',
            'pages/news/national' : 'national',
            'pages/news/international' : 'international',
            'pages/news/other' : 'other',
            'pages/contact' : 'contact'
        },

        //Initializing the application
        initialize: function () {
            var self = this;

            //Collections
            this.mainMenuCollection = new MainMenuCollection();
            this.newsMenuCollection = new NewsMenuCollection();

            //Views
            this.mainMenuView = new MainMenuView({el:'#mainMenu', collection:this.mainMenuCollection});

            this.mainMenuCollection.fetch({success: function(collection) {
                self.mainMenuView.collection=collection;
                self.mainMenuView.render();
            }});

            this.newsMenuCollection.fetch({success: function(newscollection) {
                self.newsMenuView.newscollection=newscollection;
                self.newsMenuView.render();
            }});

            Backbone.history.start({
                pushState: false
            });

        },

        //Default route.
        index: function () {
            var self = this;
        },

        about: function() {
            this.aboutView = new AboutView({el:'#topContent'}).render();
        },

        news: function() {
            this.newsView = new NewsView({el:'#topContent'}).render();
            this.subMenuView = new SubMenuView({el:'#subMenu', collection:this.subMenuCollection}).render();
        },


        about: function() {
            this.aboutView = new AboutView({el:'#topContent'}).render();
        },

        contact: function() {
            this.contactView = new ContactView({el:'#topContent'}).render();
        },

        national: function() {
            this.nationalView = new NationalView({el:'#subContent_2'}).render();
        },

        international: function() {
            this.internationalView = new InternationalView({el:'#subContent_2'}).render();
        },

        other: function() {
            this.otherView = new OtherView({el:'#subContent_2'}).render();
        }                       


    });

    return Router;
}

2 个答案:

答案 0 :(得分:0)

这看起来与此类似的问题:Backbone Router on any page change event

您可以使用Routefilter插件,并在功能之前定义,这可以清除不再可见的视图。

答案 1 :(得分:0)

好的,让我们简化你想要实现的目标:

  • 转到“新闻”路线,添加其他菜单
  • 远离“新闻”路线,删除新闻子菜单

现在在vanilla Backbone中,唯一的方法就是手动完成。像这样:

var Router = Backbone.Router.extend({       

        onBeforeRoute: function () {
            if (this.subMenuView) this.subMenuView.$el.empty();

            // anything else you need to do
        },

        ...

        //Default route.
        index: function () {
            this.onBeforeRoute();

            var self = this;
        },

        about: function() {
            this.onBeforeRoute();           

            this.aboutView = new AboutView({el:'#topContent'}).render();
        },

        news: function() {
            this.onBeforeRoute();

            this.newsView = new NewsView({el:'#topContent'}).render();
            this.subMenuView = new SubMenuView({el:'#subMenu', collection:this.subMenuCollection}).render();
        },

        ...
}

查看the docs here以查看删除方法。

我建议的另一件事是在初始化方法中实例化你的视图。如果你每次触发路由时都会继续重新创建它们,那么旧视图会在内存中挂起并仍然绑定到DOM,如果你的视图绑定到数据等,会导致奇怪的问题。我可以看到你发生了一些事情来阻止它你实现的close方法,但看起来你实际上并没有在任何地方调用它。

另外,我会说当你第一次尝试使用Backbone时会感到沮丧,但坚持使用它,并继续阅读有关最佳实践的文章等,因为你总是需要记住Backbone不是框架!它是一个非常简单的库,它没有提供任何真正的约定或方式来构建您的应用程序(这就是许多人喜欢它的原因)。我喜欢Backbone但我实际上和Marionette一起使用它,它提供了很多很好的方法来构建你的应用程序。我建议检查一下。