MarionetteJS:有关模型属性更改的问题(事件未触发?)

时间:2013-09-13 18:11:50

标签: backbone.js marionette

此处描述的应用程序不是真正的应用程序,而仅仅是为了演示问题,并根据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不会更新。知道为什么会这样吗?

设计问题
这是设计一个不需要(或者也是错误的假设)路由器的应用程序的正确方法;或者我应该采取另一种方法?

1 个答案:

答案 0 :(得分:2)

使用以下模型定义尝试:

Entities.Contact = Backbone.Model.extend({
    defaults: {
        fileName: '',
        name: ''
    },
    initialize: function() {
        this.on("change", function(){
            console.log("model changed");
        }
    }
});

Backbone模型没有change属性:您需要在初始化程序中注册回调函数。