backbone.js构建嵌套视图和模型
backbone.js structuring nested views and models
使用backbone.js:
我有一个顶级ModelA,它包含2个属性和2个嵌套模型,ModelB和ModelC。型号B和型号C各有2个属性,如下所示:
ModelA
attributeA1
attributeA2
ModelB
attributeB1
attributeB2
ModelC
attributeC1
attributeC2
有一个ViewA用于ModelA,一个ViewB用于ModelB。ViewA的render函数在主体上放置一个新的div,而ViewB的render则创建一个h1。ViewA的初始化调用ViewB的render将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,甚至attributeC1(哪一个是兄弟姐妹/表亲)?
Q2:作为对Q1的进一步扩展,funcB1是否可以访问与ViewA相关联的DOM元素?(在本例中,#newdiv?)
Q3:一般来说,我如何定义如上所述的视图和模型之间的关联,以便将所有内容正确地联系在一起?
我意识到这个问题有些抽象,但任何人都感谢任何帮助或指导。
为了能够访问相关模型上的属性,模型必须了解它与哪些模型相关。Backbone.js不会隐式处理关系或嵌套,这意味着你必须自己确保模型之间相互了解。要回答您的问题,一种方法是确保每个子模型都有一个"父"属性。通过这种方式,您可以先遍历嵌套到父对象,然后再遍历到您所知道的任何兄弟姐妹。
更具体地回答你的问题。当初始化模型a时,您可能正在创建模型B和模型C,我建议在执行此操作时设置一个到父模型的链接,如下所示:
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元素中。
"Can I"问题的一般答案总是"是的,只要你愿意写代码。"Backbone背后的要点是提供模型和视图的强大分离。如果B1引用了A1,而A1引用了C1,那么您完全能够创建方法并设置规则,B1可以通过这些方法修改A1和C1等等。
应该设置视图以接收来自其各自模型的CRUD事件。如果用户对B1view做了修改B1model的事情,而B1model又修改了A1model,那么A1model应该生成A1view接收的事件,并导致A1view的重新渲染,依此类推。它应该像魔术一样发生。(在实践中,需要一些时间才能发挥正确的魔力,但我发现Backbone非常强大。BackboneRelational有助于实现您在这里描述的功能。)
上述解决方案是正确的,但存在一些问题。
initialize: function(){
this.viewB = new ViewB();
this.viewB.parentView = this;
$(this.el).append(this.viewB.el);
}
主要是,模型的toJSON()现在返回过时的数据。我在backbone.js插件中发布了一个解决方案来解决这个问题。欢迎您使用它。
您可以使用一些扩展,Backbone Formshttps://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-部分模板的模板。
这里的重要部分是type: 'NestedModel'
和template: 'templateXXX'
。
这个插件有一些限制,但你可以在https://github.com/documentcloud/backbone/wiki/Extensions%2C-插件%2C资源。
有一个主干插件backbone-relationsal.js,它为backbone提供了模型之间的一对一、一对多和多对一关系。
我认为这个js会满足你的需求。Vist BackboneRelational获取更多文档。
- 角度指令没有更新模型视图
- “渲染骨干模型视图”返回未定义的结果
- 轮询更新主干模型/视图的请求
- 节点.js中的模型-视图-控制器模式
- 图像数据中的更改未反映在模型视图中
- 自定义 ngModel 指令以支持 jquery 插件中的模型>视图绑定
- 优化显示简单项目列表的模型/视图
- 建议:在JavaScript中难以使用模型视图控制器
- 将三维世界矢量转换为模型视图矩阵
- 在主干模型/视图上处理更复杂的验证逻辑(必填字段等)的最佳方式
- AngularJS在POST http请求上更新模型/视图
- web应用程序模型视图中的Java脚本
- 我的第一个骨干模型/视图.我的思路对吗?
- Knockoutjs的日期时间字段更新不会刷新模型视图
- Backbone.js中的嵌套集合/模型视图管理
- Javascript“this"模型视图演示器设计中的问题
- 模型视图控制器-javascript mvc框架设计实践,用于编辑就地界面
- 模型视图控制器-任何使用javascript mvc的人
- 模型视图控制器-我们是否在使用JavaScriptMVC(MVVM)框架,如Backbone.js、Angular等
- 模型视图控制器-AngularJS中是否可以在经典的javascript函数中使用数据绑定