此处描述的应用程序不是真正的应用程序,而仅仅是为了演示问题,并根据David Sulc一书中描述的contactmanager应用程序的精神创建。
Image showing application layout
上图中的应用程序可以执行以下操作:
- 启动时,仅显示区域1
- 用户可以上传图片,该图片也会在集合中创建第一个联系人
- 上传完成后,区域2和3变为活动状态
- 区域2允许用户裁剪图像并更改联系属性(名称/年龄等)
- 区域3显示所有已创建联系人的集合视图,并显示创建新联系人的按钮
- 每个条目的区域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的itemViews不会更新。知道为什么会这样吗?
设计问题
这是设计一个不需要(或者也是错误的假设)路由器的应用程序的正确方法;或者我应该采取另一种方法?
答案 0 :(得分:2)
使用以下模型定义尝试:
Entities.Contact = Backbone.Model.extend({
defaults: {
fileName: '',
name: ''
},
initialize: function() {
this.on("change", function(){
console.log("model changed");
}
}
});
Backbone模型没有change
属性:您需要在初始化程序中注册回调函数。