backbone.js构造嵌套视图和模型

for*_*ice 71 javascript backbone.js

使用backbone.js:

我有一个顶级ModelA,包含2个属性和2个嵌套模型,ModelB和ModelC.ModelB和ModelC各有2个属性如下:

ModelA
    attributeA1
    attributeA2
    ModelB
        attributeB1
        attributeB2
    ModelC
        attributeC1
        attributeC2
Run Code Online (Sandbox Code Playgroud)

ModelA有ViewA,ModelB有ViewB.ViewA的渲染功能在主体上放置一个新的div,而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?
Run Code Online (Sandbox Code Playgroud)

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

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

问题3:一般情况下,如何定义视图和模型之间的关联,如上所述,以便一切正确联系在一起?

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

Jen*_*Alm 73

为了能够在相关模型上获得属性,模型必须具有与其相关的模型的某种知识.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以通过调用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();
    }

});
Run Code Online (Sandbox Code Playgroud)

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

  • 是否有任何内存泄漏,因为这会产生循环引用? (8认同)