javascript backbone模板 backbone.js构建嵌套视图和模型




backbone使用 (4)

“我可以”这个问题的一般答案总是“是的,只要你愿意写代码”。 Backbone背后的重点是为模型和视图提供强有力的分离。 如果B1具有对A1的引用,并且A1具有对C1的引用,那么您完全可以创建方法并设置B1可以修改A1和C1等的规则。

这些视图应该设置为从它们各自的模型中接收CRUD事件。 如果用户使用B1view修改B1model,B1model又修改A1model,则A1model应生成A1view接收并导致A1view重新渲染的事件,等等。 它应该像魔术一样发生。 (实际上,获得魔力需要一些时间,但是我发现Backbone非常强大,而BackboneRelational可以帮助解决诸如此处描述的问题。)

使用backbone.js:

我有一个顶级ModelA,它包含2个属性和2个嵌套模型ModelB和ModelC。 ModelB和ModelC每个都有两个属性,如下所示:

ModelA
    attributeA1
    attributeA2
    ModelB
        attributeB1
        attributeB2
    ModelC
        attributeC1
        attributeC2

ModelA有ViewA,ModelB有ViewB。 ViewA的渲染函数将一个新的div放到body上,而ViewB的渲染函数创建一个h1。 ViewA的初始化调用ViewB的渲染器,将h1插入到新的div中。 这种分离背后的基本原理是,h1可能会发生变化,并需要独立于ViewA进行重新渲染。

ViewA
    initialise: 
        //call ViewA's own render function
        this.render() 

        //call ViewB's render function that further modifies the $("#new") div created earlier.
        $("#new").append(ViewB.render().el)

    //ViewA's own render function
    render: //place <div id="new"></div> onto 'body'

ViewB
    render: //create a <h1></h1>
    funcB1: //can this access it's parent ModelA's attributes and other objects?

Q1:ViewB有一个函数funcB1。 这个函数可以访问它的父模型的属性吗? 属性,如attributeA1,甚至属性C1(这将是兄弟/表亲)?

Q2:作为Q1的进一步扩展,funcB1可以访问与ViewA相关的DOM元素吗? (在这个例子中,#new div?)

问题3:一般来说,我如何定义上述视图和模型之间的关联,以便所有东西都能正确连接在一起?

我意识到这个问题有点抽象,但任何感谢任何帮助或指导。


Answer #1

您可以使用一些扩展,例如Backbone-Forms https://github.com/powmedia/backbone-forms 。 按照你的用例定义一个模式,如:

var ModelB = Backbone.Model.extend({
    schema: {
        attributeB1: 'Text',
        attributeB2: 'Text'
    }
});

var ModelC = Backbone.Model.extend({
    schema: {
        attributeC: 'Text',
    }
});

var ModelA = Backbone.Model.extend({
    schema: {
        attributeA1: 'Text',
        attributeA2: 'Text',
        refToModelB: { type: 'NestedModel', model: ModelB, template: 'templateB' },
        refToModelC: { type: 'NestedModel', model: ModelC, template: 'templateC' }
    }
});

查看部分模板的https://github.com/powmedia/backbone-forms#customising-templates

这里的重要部分是type: 'NestedModel'template: 'templateXXX'

这个插件有一些限制,但你可以在https://github.com/documentcloud/backbone/wiki/Extensions%2C-Plugins%2C-Resources看看其他人。


Answer #2

为了能够涉及相关模型的属性,模型必须具有关于与其相关的模型的某种知识。 Backbone.js并不隐式处理关系或嵌套,这意味着您必须确保模型具有彼此的知识。 要回答你的问题,一种方法是确保每个孩子模型都有一个“父”属性。 这样,您可以先将嵌套遍历到父对象,然后再遍历到您所知道的任何兄弟对象。

更具体的你的问题。 在初始化modelA时,您可能正在创建modelB和modelC,我建议在执行此操作时设置指向父模型的链接,如下所示:

ModelA = Backbone.Model.extend({

    initialize: function(){
        this.modelB = new modelB();
        this.modelB.parent = this;
        this.modelC = new modelC();
        this.modelC.parent = this;
    }
}

这样,您可以通过调用this.parent来访问任何子模型函数中的父模型。

关于你的观点,在做嵌套骨干视图时,我发现通过使用视图的tagName选项让每个视图代表一个HTML标记变得更容易。 我会写下你的看法:

ViewA = Backbone.View.extend({

    tagName: "div",
    id: "new",

    initialize: function(){
       this.viewB = new ViewB();
       this.viewB.parentView = this;
       $(this.el).append(this.viewB.el);
    }
});

ViewB = Backbone.View.extend({

    tagName: "h1",

    render: function(){
        $(this.el).html("Header text"); // or use this.options.headerText or equivalent
    },

    funcB1: function(){
        this.model.parent.doSomethingOnParent();
        this.model.parent.modelC.doSomethingOnSibling();
        $(this.parentView.el).shakeViolently();
    }

});

然后在您的应用程序初始化代码中(例如在您的控制器中),我将启动ViewA并将其元素放入body元素中。


Answer #3

骨干插件Backbone-relational.js为骨干模型提供了一对一,一对多和多对一的关系。

我认为这个JS会满足你的需求。 Vist BackboneRelational获取更多文档。







backbone.js