我遵循 David Sulc 的书 Backbone.Marionette.js: A Gentle Introduction 中的建议。 (下一本书还介绍了如何使用 require https://leanpub.com/structuring-backbone-with-requirejs-and-marionette 构建同一个项目)他使用的代码示例可在 github 上找到,因此您可以查看最后一个示例,如果您不了解他会做什么;不想买这本书,但我真的很推荐它,因为它确实帮助了我如何构建我的项目。
首先我设置了一个实体模块。文件的结构也遵循这个我有一个实体文件夹,它有单独的实体。
每个实体文件都涉及该特定实体的所有操作和结构。我喜欢这种方法,因为当我想编辑实体结构或从服务器获取数据的方法时,我只需要去一个地方进行此更改。
与实体的交互通过牵线木偶req/res系统处理。通过这种方式,您可以向应用程序的其余部分公开处理程序,但他们不需要关心如何处理该请求,只要它带回所需的响应即可。
这是我的一个实体的示例,以说明我的意思 - 我的应用程序需要一个在各个阶段称为位置的集合,所以这是在应用程序早期加载的东西,然后在整个生命周期中可用。
//i am using require so i define my app to use
define(["app", ], function(MyApp) {
//All of this will be added to the Entities module so if i want direct access
//i can go Myapp.Entities.whateverEntityIhaveDeclared
MyApp.module("Entities", function(Entities, MyApp, Backbone, Marionette, $, _) {
//model (nothing new here)
Entities.Position = Backbone.Model.extend({
urlRoot: "api/positions",
defaults: {
name: "",
}
});
//collection again nothing new here
Entities.PositionCollection = Backbone.Collection.extend({
url: "api/positions",
model: Entities.Position,
comparator: "name"
});
//an init function to attach a position collection onto Entities module so it can be available throughout my app
var initializePositions = function() {
if (Entities.positions === undefined) {
Entities.positions = new Entities.PositionCollection();
}
};
//
var API = {
//returns a jquery deferred promise so that this request can easily be handled async
loadPositionEntitiesRemote: function() {
//init positions make's sure i have the collectoin avaliable if it
//has not yet been defined
initializePositions();
//setup defer object
var defer = $.Deferred();
//I actually use a custom sever object here when dealing
//with ajax requests
//but because my app always go through this API i can
//easily swap out how the collection is retrieved.
// Here is an example using backbones fetch
Entities.positions.fetch({
success: function() {
defer.resolve();
},
error: function(data) {
defer.reject(data);
}
});
//setup promise to return
var promise = defer.promise();
return promise;
},
//get the positions collection from here i could
//directly access the attributes or add to the collection
refrencePositionEntities: function() {
initializePositions();
return Entities.positions;
},
//get a position from the collection based on id
//
getPositionEntity: function(positionId) {
initializePositions();
return Entities.positions.get(positionId);
}
};
//setup handlers for the app to use
MyApp.reqres.setHandler("position:entities:remote", function() {
return API.loadPositionEntitiesRemote();
});
MyApp.reqres.setHandler("position:entities:refrence", function() {
return API.refrencePositionEntities();
});
MyApp.reqres.setHandler("position:entity", function(id) {
return API.getPositionEntity(id);
});
MyApp.reqres.setHandler("position:entity:new", function(position) {
return new Entities.Position(position);
});
});
return;
});
现在在我的应用程序中使用它是一个现在如何使用它的示例
someFunction: function(){
//so early in the app i will get the positions
var positionPromise = MyApp.request("position:entities:remote");
$.when(positionPromise).done(function() {
//do what ever as data has been loaded
}).fail(function(data){
//something failed so handle here might through up an error page but up to you
}).always(function(){
//something to always do no matter if fail or sucess
});
}
anotherFunction: function(){
//later in the app in another controller i might to get the collection
// I could also get it through MyApp.Entities.positions but i rather use the
// API set up so if i ever decided i want to add so checks or something in
// when retrieving the collection its super easy
var positionsCollection = MyApp.request("position:entities:refrence");
}
不确定我是否在解释这一点上做得很好,但如果您正在寻找关于木偶中良好设计的想法,请查看这本书,因为它比我刚刚做的更好地解释了这一点