預P.S:我已經爲你與我下面寫的代碼要點:我與由其他答案建議的發佈/訂閱(「觀察者模式」)同意 https://gist.github.com/2863979
。然而,我也會使用Require.js和Backbone的強大功能。
艾迪奧斯馬尼寫了一些偉大的!
http://addyosmani.com/resources/essentialjsdesignpatterns/book/ http://addyosmani.com/writing-modular-js/ http://addyosmani.github.com/backbone-fundamentals/
關於與骨幹一起使用AMD(在Require.js實現)很酷的事情是,你解決一些問題,你用」:關於JavaScript的設計模式和有關建築物主幹應用程序資源通常有。
通常你會定義類,這些存儲在某種命名空間中的方式,如:
MyApp.controllers.Tasks = Backbone.Controller.extend({})
這是好的,只要你在一個文件中定義的大多數事情,當你開始添加越來越多不同的文件混合它變得不那麼強大,你必須開始關注你如何加載不同的文件,controllers\Tasks.js
models\Task.js
之後等等。當然你可以按照正確的順序編譯所有的文件等,但它遠非完美。
最重要的是,非AMD方式的問題在於,您必須更緊密地將視圖嵌套在對方內。可以這樣說:
MyApp.classes.views.TaskList = Backbone.View.extend({
// do stuff
});
MyApp.views.App = Backbone.View.extend({
el: '#app',
initialize: function(){
_.bindAll(this, 'render');
this.task_list = new MyApp.classes.views.TaskList();
},
render: function(){
this.task_list.render();
}
});
window.app = new MyApp.views.App();
一切都很好,但這可以成爲一場噩夢。
隨着AMD可以定義一個模塊,並給它一些依賴關係,如果你有興趣在此工作方式讀取上面的鏈接,但上面的例子是這樣的:
// file: views/TaskList.js
define([], function(){
var TaskList = Backbone.View.extend({
//do stuff
});
return new TaskList();
});
// file: views/App.js
define(['views/TaskList'], function(TaskListView){
var App = Backbone.View.extend({
el: '#app',
initialize: function(){
_.bindAll(this, 'render');
},
render: function(){
TaskListView.render();
}
});
return new App();
});
// called in index.html
Require(['views/App'], function(AppView){
window.app = AppView;
});
請注意,在你會返回實例的意見的情況下,我的收藏就此別過,但對於模型我回班:
// file: models/Task.js
define([], function(){
var Task = Backbone.Model.extend({
//do stuff
});
return Task;
});
這似乎有點吃不消起初,人們可能會覺得「哇,這是矯枉過正」。但是,當你必須使用相同的對象在許多不同模塊的真正威力變得明確,比如集合:
// file: models/Task.js
define([], function(){
var Task = Backbone.Model.extend({
//do stuff
});
return Task;
});
// file: collections/Tasks.js
define(['models/Task'], function(TaskModel){
var Tasks = Backbone.Collection.extend({
model: TaskModel
});
return new Tasks();
});
// file: views/TaskList.js
define(['collections/Tasks'], function(Tasks){
var TaskList = Backbone.View.extend({
render: function(){
_.each(Tasks.models, function(task, index){
// do something with each task
});
}
});
return new TaskList();
});
// file: views/statistics.js
define(['collections/Tasks'], function(Tasks){
var TaskStats = Backbone.View.extend({
el: document.createElement('div'),
// Note that you'd have this function in your collection normally (demo)
getStats: function(){
totals = {
all: Tasks.models.length
done: _.filter(Tasks, function(task){ return task.get('done'); });
};
return totals;
},
render: function(){
var stats = this.getStats();
// do something in a view with the stats.
}
});
return new TaskStats();
});
注意,「任務」的對象恰恰是在這兩種觀點是相同的,所以同樣的車型,狀態等。這比在一個時間點創建Tasks集合的實例然後始終參考整個應用程序要好得多。
至少對我來說,使用Require.js和Backbone已經帶走了一個令人費解的巨大難題,在哪裏實例化了什麼。爲此使用模塊非常有用。我希望這也適用於你的問題。
p.s.還請注意,您也可以將Backbone,Underscore和jQuery作爲模塊添加到您的應用中,儘管您不需要,但可以使用普通腳本標記加載它們。
@Luc Perkins建議Backbone Aura,你可能想要檢查一下Marionette。木偶可能比Aura更成熟 –
我認爲TaskCreateView和TaskPaneView是不必要的。 TaskCreateView特別不應該在那裏,因爲它沒有任何模型來表示。將任務創建合併到TaskListView本身中。也許一個輸入控件可以讓用戶添加新的任務。當用戶按Enter鍵時,將它添加到Tasks集合中。我假設您正在偵聽收集上的添加事件,以便您可以將新創建的TaskView添加到TaskListView。只要用戶關注WidgetView,就可以調出TaskListView。 – Vishal