1

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

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

4

1 回答 1

2

尝试使用以下模型定义:

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

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

于 2013-09-13T19:01:42.370 回答