使用Backbone.js管理基本接口状态的更好方法

时间:2014-11-17 20:47:18

标签: javascript backbone.js

我是Backbone.js的新手,我想知道是否有任何我想要完成的常见做法。我的目标是在我的应用程序中管理一些基本的UI状态。

例如,跟踪正在打开或关闭的菜单:

(function() {
App.Models.Masthead = Backbone.Model.extend({
    defaults: {
        primaryNavClosed: true
    },

    togglePrimaryNavState: function() {
        this.set('primaryNavClosed', !this.get('primaryNavClosed'));
    }
});

App.Views.Masthead = Backbone.View.extend({
    el: '#masthead',
    initialize: function() {
        var model = this.model;
        this.primaryNav = this.$('#primary-nav');

        // Close the nav menu when anything outside of the menu is clicked.
        $("body").click(function() {
            model.set('primaryNavClosed', true);
        });
        // Do not close nav menu if the nav menu itself is clicked
        this.primaryNav.click(function() {
            return false;
        });

        this.listenTo(this.model, 'change:primaryNavClosed', this.render);
    },

    events: {
        'click #mobile-nav-hamburger': 'togglePrimaryNavState'
    },

    togglePrimaryNavState: function() {
        this.model.togglePrimaryNavState();
        // don't auto close the menu
        return false;
    },

    openPrimaryNav: function() {
        this.model.set('primaryNavClosed', false);
    },

    closePrimaryNav: function() {
        this.model.set('primaryNavClosed', true);
    },

    render: function() {
        if(this.model.get('primaryNavClosed')) {
            this.primaryNav.addClass('closed');
        } else {
            this.primaryNav.removeClass('closed');
        }
        return this;
    }
});
App.masthead = new App.Models.Masthead;
new App.Views.Masthead({ model: App.masthead });
})();

HTML供参考:

<div id="masthead">
<div class="banner">
    <a href="/"><span>Title</span></a>
</div>
<a href="#" id="mobile-nav-hamburger"></a>
<nav id="primary-nav" class="closed">
    <ul>
        <!-- nav items will go here eventually -->
    </ul>
</nav>
</div>

这样就可以了,我只是觉得这种感觉很糟糕。我很欣赏这样一个事实:我可以从我的应用程序的其他部分更新模型中的数据,并且视图将自动响应而无需大量繁琐的工作......即使是在这种情况下简单地显示导航菜单的东西。

很难找到讨论此类行为的常见模式的文章,并且非常感谢有关如何改进这些模式的任何想法。

提前致谢!

1 个答案:

答案 0 :(得分:2)

就个人而言,我不会打扰模型,只是将状态直接存储在视图中。

(function() {
App.Views.Masthead = Backbone.View.extend({
    el: '#masthead',
    initialize: function() {
        var view = this;
        this.primaryNavClosed = true;
        this.primaryNav = this.$('#primary-nav');

        // Close the nav menu when anything outside of the menu is clicked.
        $("body").click(function() {
            view.primaryNavClosed = true;
            view.render()
        });

        // Do not close nav menu if the nav menu itself is clicked
        this.primaryNav.click(function() {
            return false;
        });
    },

    events: {
        'click #mobile-nav-hamburger': 'togglePrimaryNavState'
    },

    togglePrimaryNavState: function() {
        this.primaryNavClosed = !this.primaryNavClosed;
        this.render();
    },

    openPrimaryNav: function() {
        this.primaryNavClosed = false;
        this.render()
    },

    closePrimaryNav: function() {
        this.primaryNavClosed = true;
        this.render();
    },

    render: function() {
        if(this.primaryNavClosed) {
            this.primaryNav.addClass('closed');
        } else {
            this.primaryNav.removeClass('closed');
        }
        return this;
    }
});
new App.Views.Masthead();
})();

话虽如此,我认为你实际上并不需要在你的特定情况下存储状态,因为所有状态都只是确定是否添加或删除了CSS类 - 为什么不将它显式化?

(function() {
App.Views.Masthead = Backbone.View.extend({
    el: '#masthead',
    initialize: function() {
        var view = this;
        this.primaryNav = this.$('#primary-nav');

        // Close the nav menu when anything outside of the menu is clicked.
        $("body").click(function() {
            view.closePrimaryNav();
        });

        // Do not close nav menu if the nav menu itself is clicked
        this.primaryNav.click(function() {
            return false;
        });
    },

    events: {
        'click #mobile-nav-hamburger': 'togglePrimaryNavState'
    },

    togglePrimaryNavState: function() {
        this.primaryNav.toggleClass( 'closed' );
    },

    openPrimaryNav: function() {
        this.primaryNav.removeClass( 'closed' );
    },

    closePrimaryNav: function() {
        this.primaryNav.addClass( 'closed' );
    }
});
new App.Views.Masthead();
})();