首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >backbone.js构建嵌套视图和模型

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

Stack Overflow用户
提问于 2011-06-15 13:51:46
回答 5查看 34.1K关注 0票数 71

使用backbone.js:

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

代码语言:javascript
复制
ModelA
    attributeA1
    attributeA2
    ModelB
        attributeB1
        attributeB2
    ModelC
        attributeC1
        attributeC2

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

代码语言:javascript
复制
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,或者甚至是attributeC1 (哪一个是兄弟/堂兄弟)?

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

Q3:一般来说,我如何定义如上所述的视图和模型之间的关联,以便一切都正确地联系在一起?

我知道这个问题有点抽象,但感谢任何人的帮助或指导方针。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-25 15:26:58

为了能够访问相关模型上的属性,模型必须具有关于它与哪些模型相关的某种知识。Backbone.js不会隐式地处理关系或嵌套,这意味着您必须确保模型之间相互了解。要回答你的问题,一种方法是确保每个子模型都有一个“parent”属性。这样,您可以先遍历嵌套到父级,然后再向下遍历到您所知道的任何兄弟项。

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

代码语言:javascript
复制
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标记会更容易一些。我会这样写你的观点:

代码语言:javascript
复制
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元素中。

票数 73
EN

Stack Overflow用户

发布于 2011-06-16 02:05:25

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

视图应该被设置为从它们各自的模型接收CRUD事件。如果用户使用B1view修改了B1model,而B1model又修改了A1model,那么A1model应该生成一个事件,由A1view接收并重新呈现A1view,依此类推。它应该像魔术一样发生。(在实践中,需要一些时间才能让魔术变得正确,但我已经找到了真正强大的主心骨。BackboneRelational可以帮助完成您在这里所描述的事情。)

票数 3
EN

Stack Overflow用户

发布于 2011-09-15 03:56:50

上面的解决方案是正确的,但存在一些问题。

代码语言:javascript
复制
initialize: function(){
  this.viewB = new ViewB();
  this.viewB.parentView = this;
  $(this.el).append(this.viewB.el);    
}

主要是模型的toJSON()现在返回陈旧的数据。我已经在backbone.js plugin中发布了一个解决方案来解决这个问题。欢迎您使用它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6353607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档