2014-08-28 114 views
3

我不明白如何使用browserify在不同視圖之間共享某種「單例」應用程序狀態持有對象模型。 書籍和教程經常使用全局命名空間,如:Browserify + Backbone.js「ApplicationState」共享模塊

var app = app || {}; 

我有一個簡單的例子應用程序,它包括:

MenuView.js

app.js

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

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

new MenuView(); 
new ContainerView(); 

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骨幹=需要( '骨幹');

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

module.exports = new ApplicationState(); 

ApplicationState模塊是否真的只創建一次(緩存)? 還是有重新創建/重置模塊的風險?

我用例的最佳實踐是什麼?萬分感謝。

+0

我想這是好的,你可以檢查多少ApplicationState的情況下,將被創建,加入console.count( 'Application State')在ApplicationState.js文件中並在控制檯中查看輸出。 。 – 2014-08-28 21:25:16

+0

'這$ el.html(ApplicationState.get( 'currentView'));'也許應該是'這$ el.html(ApplicationState.get( 'currentView')$ EL);' – 2014-08-29 02:46:20

回答

5

是的,在你給的例子中只會有一個ApplicationState。只要運行js文件,Browserify就會執行任何跟在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
+0

好的非常感謝你很多,我會看看談話。你能解釋一下路由器如何適合我的例子嗎?再次感謝你! – 2014-08-29 08:54:19

+1

當然。我用一個(最小的)路由器例子更新了我的答案。 – Marshall 2014-08-29 16:43:08