【问题标题】:Browserify+Backbone.js "ApplicationState" shared moduleBrowserify+Backbone.js "ApplicationState" 共享模块
【发布时间】:2014-10-22 12:36:23
【问题描述】:

我不明白如何使用 browserify 在不同视图之间共享某种“单例”应用程序状态保持对象模型。 书籍和教程通常使用全局命名空间,例如:

var app = app || {};

我有一个简单的示例应用程序,其中包括:

app.js

var $ = require('jquery');
var Backbone = require('backbone');
Backbone.$ = $;

var MenuView = require('./views/MenuView');
var ContainerView = require('./views/ContainerView');

new MenuView();
new ContainerView();

MenuView.js

var Backbone = require('backbone');
var ApplicationState = require('../models/ApplicationState');

module.exports = Backbone.View.extend({
    el: '#menuView', 
    events: {
        'click .menuLink': 'changePage'
    },
    changePage: function(event) {
        event.preventDefault();
        var viewName = $(event.target).attr('data-view');
        ApplicationState.set('currentView',viewName);
    }
});

ContainerView.js

var Backbone = require('backbone');
var ApplicationState = require('../models/ApplicationState');

module.exports = Backbone.View.extend({
    el: '#containerView', 
    initialize: function() {
        this.listenTo( ApplicationState, 'change', this.render );   
        this.render();
    },
    render: function() {
        this.$el.html( ApplicationState.get('currentView') );
    },
    close: function() {
        this.stopListening();
    }
});

这似乎使用这种方法工作:

ApplicationState.js var Backbone = require('backbone');

var ApplicationState = Backbone.Model.extend({
    defaults: {
        currentView: 'TransactionListView'
    }
});

module.exports = new ApplicationState();

ApplicationState 模块真的只创建一次(缓存)吗? 还是有重新创建/重置模块的风险?

我的用例的最佳做法是什么?非常感谢。

【问题讨论】:

  • 我想没关系,您可以通过在 ApplicationState.js 文件中添加 console.count('Application State') 来检查将创建多少个 ApplicationState 实例并在控制台中查看输出。
  • this.$el.html( ApplicationState.get('currentView') ); 应该是this.$el.html( ApplicationState.get('currentView').$el );

标签: javascript node.js backbone.js browserify commonjs


【解决方案1】:

是的,您给出的示例中只有一个 ApplicationState。 Browserify 会在 js 文件运行后立即执行 module.exports = 之后的任何内容,然后将需要该文件的任何内容传递给结果的引用。

但是,通常更好的做法是避免在视图之间以这种方式共享状态,而是使用委托给子视图的父视图。有多种设置方法。有关组织主干应用程序的最佳实践的想法,请查看此演讲:https://www.youtube.com/watch?v=Lm05e5sJaE8

对于您给出的示例,我会高度考虑使用Backbone's Router。 在您的示例中,您有一个更改“主”视图的导航。 Backbone.Router 拦截导航并根据您调用视图方法的指定路线检查它。例如:

router.js

module.exports = Backbone.Router.extend({
    initialize: function(options){
        this.ContainerView = new ContainerView();
    },
    routes: {
        'transactions': 'showTransactionListView',
        'transaction/:id': 'showTransactionDetailView'
    },
    showTransactionListView: function() {
        this.ContainerView.render('TransactionListView');
    },
    showTransactionDetailView: function(id) {
        this.ContainerView.render('TransactionDetailView', id);
    }
});

然后任何指向#transations 的链接(或者如果您使用的是Backbone History,则只是transactions)将调用您的ContainerView.render('TransactionListView')。而且,作为奖励,如果您重新加载页面,您仍然会看到 TransactionListView

其他说明:

  • 您需要确保在替换旧视图时丢弃它们(通过在它们上调用.remove())以避免内存泄漏。 Further Reading
  • 您可以为路由器添加一些灵活性,并使用控制器模式通过this nifty plugin 呈现子视图

【讨论】:

  • 好的,非常感谢,我去看看谈话。你能解释一下路由器如何适合我的例子吗?再次感谢您!
  • 当然。我已经用(最小的)路由器示例更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 2016-03-05
  • 2020-05-03
相关资源
最近更新 更多