此处描述的应用程序不是真正的应用程序,而只是为了演示问题,并按照 David Sulc 的书中描述的联系人管理器应用程序的精神创建。
上图中的应用程序可以执行以下操作:
- 启动时,仅显示区域 1
- 用户可以上传图片,该图片也会在集合中创建第一个联系人。
- 上传完成后,区域 2 和 3 将变为活动状态。
- 区域 2 允许用户裁剪图像并更改联系人属性(姓名/年龄等)
- 区域 3 显示所有已创建联系人的 collectionView 并显示用于创建新联系人的按钮。
- 每个条目的区域 3 都有一个编辑,应该在上面的视图中加载联系人。
- 当要添加第二个(或以后)联系人时,区域 2 将禁用,直到上传了新图像。
技术方法
- 拥有联系模型和联系模型。
- 因为我不改变地区的观点,所以我不打算使用路由器。
- 有办法跟踪当前处于活动状态的模型。
编码
// File: js/app.js
// Define application
var ContactManager = new Marionette.Application();
// Define regions
ContactManager.addRegions({
firstRegion: "#first-region",
secondRegion: "#second-region",
tirdRegion: "#third-region"
});
// Itemviews (usually in modules, but for short it's here)
var region1View = Marionette.ItemView.extend({
template: "#a-template",
model: ContactManager.request("contacts:active");
});
ContactManager.firstRegion.show(region1View);
.
//File: js/apps/entities/canvas.js
ContactManager.module('Entities', function (Entities, ContactManager, Backbone, Marionette, $, _) {
Entities.Contact = Backbone.Model.extend({
defaults: {
fileName: '',
name: ''
},
change: function() {
console.log('bla');
}
});
Entities.contactCollection = Backbone.Collection.extend({
model: Entities.Contact
});
var contacts;
var activeCanvasCID;
var initializeCanvas = function () {
contacts = new Entities.CanvasCollection([
{
name: "John Doe"
}
]);
};
var API = {
getContactEntities: function () {
return contacts;
},
getActiveContactsEntity: function () {
if (!contacts) {
// if we don't have any contacgts yet, create the first
initializeContact();
}
if (activeContactCID === undefined) {
// No active contact yet, get the first model from collection
activeContactCID = contacts.at(0).cid;
}
return contact.get(activeCanvasCID);
},
setActiveContactsEntity: function (cid) {
if (activeContactCID !== cid) {
activeContactCID = cid;
ContactManager.vent.trigger("ActiveCanvasChanged");
}
}
};
ContactManager.reqres.setHandler("contacts:entities", function () {
return API.getContactEntities();
});
ContactManager.reqres.setHandler("contacts:active", function () {
return API.getActiveContactsEntity();
});
ContactManager.commands.setHandler("contacts:setActiveEntity", function(cid){
API.setActiveContactsEntity(cid);
});
});
免责声明:可能存在一些语法错误,但这是半伪代码
现在,例如,如果我在任何其他模块中执行以下操作(例如,当图像已上传并且我想在当前活动模型中设置文件名时):
var activeModel = ContactManager.request("contacts:active");
activeModel.set("fileName","image.png");
问题
现在,当我执行后者时,更改 (console.log) 事件不会触发。此外,也引用此 activeModel 的 itemView 不会更新。知道为什么会这样吗?
设计问题
这是设计不需要(或者也是错误的假设)路由器的应用程序的正确方法吗?还是我应该采取另一种方法?