在创建嵌套骨干型号骨干关系 [英] Creating nested models in Backbone with Backbone-relational
问题描述
我想用骨干关系有嵌套模式在我的backbone.js 的应用。
I would like to use backbone-relational to have nested models in my backbone.js application.
我已经能够按照实例文档中创建嵌套的对象(例如,一个一对多的关系)。不过,我不明白如何绑定的方式,将更新上层对象下级元素。我想工作的应用是一个非常有用的教程。
I have been able to follow the examples in the documentation to create nested objects (e.g. one-to-many relations). However I don't understand how to bind the lower level elements in a way that will update the upper level objects. I think a working application would be a very helpful tutorial.
所以我的问题是:我如何延长托多斯教程使用骨干关系
这样:
So my question is: How do I extend the Todos tutorial using backbone-relational
so that:
- 可以添加/删除子项为每个项目
- 在任何子项目双击编辑它(就像当初的Todo例子)
- 单击某个项目隐藏/显示其子项
- 子项都没有单独牵强,但仅仅是的待办事项数组属性
更新:我有创造了这个问题一个的jsfiddle。到目前为止,我有:
Update: I have created a jsfiddle for this question. So far I have:
- 进口上述藤例子
- 创建一个
TodoSubitem
模式和TodoSubitemList
集 - 修改了
待办事项
模式以延长RelationalModel
而不是模式
,以的hasMany
关于TodoSubitem
- 新增了
子项模板
在html code
- Imported the Todo example mentioned above
- Created a
TodoSubitem
model and aTodoSubitemList
collection - Altered the
Todo
model to extendRelationalModel
instead ofModel
, with aHasMany
relation toTodoSubitem
- Added a
subitem-template
in the html code
但我还是不知道如何:
- 添加输入字段
子项目
出现只有当你点击一个待办事项
DIV - 都有分项数据作为
待办事项
对象的属性,但还是有TodoSubitemView
绑定DOM元素,它们(例如<李方式>
标记)
- add an input field for
subitems
that appears only when you click aTodo
div - have subitem data as an attribute of
Todo
objects, but still haveTodoSubitemView
bind DOM elements to them (e.g.<li>
tags).
推荐答案
我不认为我会建立在这种情况下单独的TodoSubItem' - 为什么不创建一个的hasMany
从Todo->的Todo关系,所以藤堂可以有0 .. * 孩子
和0..1 父
?
I don't think I'd create a separate 'TodoSubItem' in this case - why not create a HasMany
relation from Todo->Todo, so a Todo can have 0..* children
, and 0..1 parent
?
这样,您就可以重新使用的顺序逻辑(如果你改变它每收集应用),可以建立更深层次的嵌套根据需要(或限制到一定深度,如果你想为好),等等。许多事情都需要,虽然被更新,以适应这一点 - 例如,保持子视图列表,这样你就可以遍历他们每个标记为已完成,并维持(和更新)每一个排序 TodoList的
。
This way, you can re-use the order logic (if you change it to apply per collection), can create deeper nesting levels as desired (or limit that to a certain depth, if you want as well), etc. A number of things will need to be updated though, to accomodate this - for example, keep a list of child views so you can loop over them to mark each as done, and maintaining (and updating from) an ordering per TodoList
.
总之,一个可能的解决方案的一个大致的轮廓,让你开始,作为一种差异与当前版本(不好意思,这是完全未经测试,因此可能包含可怕的错误):
Anyway, a rough outline of a possible solution to get you started, as a sort of diff with your current version (sorry, it's completely untested and could thus contain horrible mistakes):
//Our basic **Todo** model has `text`, `order`, and `done` attributes.
window.Todo = Backbone.RelationalModel.extend({
relations: [{
type: Backbone.HasMany,
key: 'children',
relatedModel: 'Todo',
collectionType: 'TodoList',
reverseRelation: {
key: 'parent',
includeInJSON: 'id'
}
}],
initialize: function() {
if ( !this.get('order') && this.get( 'parent' ) ) {
this.set( { order: this.get( 'parent' ).nextChildIndex() } );
}
},
// Default attributes for a todo item.
defaults: function() {
return { done: false };
},
// Toggle the `done` state of this todo item.
toggle: function() {
this.save({done: !this.get("done")});
}
nextChildIndex: function() {
var children = this.get( 'children' );
return children && children.length || 0;
}
});
// The DOM element for a todo item...
window.TodoView = Backbone.View.extend({
//... is a list tag.
tagName: "li",
// Cache the template function for a single item.
template: _.template($('#item-template').html()),
// The DOM events specific to an item.
events: {
'click': 'toggleChildren',
'keypress input.add-child': 'addChild',
"click .check" : "toggleDone",
"dblclick div.todo-text" : "edit",
"click span.todo-destroy" : "clear",
"keypress .todo-input" : "updateOnEnter"
},
// The TodoView listens for changes to its model, re-rendering.
initialize: function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
this.model.bind( 'update:children', this.renderChild );
this.model.bind( 'add:children', this.renderChild );
this.el = $( this.el );
this.childViews = {};
},
// Re-render the contents of the todo item.
render: function() {
this.el.html(this.template(this.model.toJSON()));
this.setText();
// Might want to add this to the template of course
this.el.append( '<ul>', { 'class': 'children' } ).append( '<input>', { type: 'text', 'class': 'add-child' } );
_.each( this.get( 'children' ), function( child ) {
this.renderChild( child );
}, this );
return this;
},
addChild: function( text) {
if ( e.keyCode == 13 ) {
var text = this.el.find( 'input.add-child' ).text();
var child = new Todo( { parent: this.model, text: text } );
}
},
renderChild: function( model ) {
var childView = new TodoView( { model: model } );
this.childViews[ model.cid ] = childView;
this.el.find( 'ul.children' ).append( childView.render() );
},
toggleChildren: function() {
$(this.el).find( 'ul.children' ).toggle();
},
// Toggle the `"done"` state of the model.
toggleDone: function() {
this.model.toggle();
_.each( this.childViews, function( child ) {
child.model.toggle();
});
},
clear: function() {
this.model.set( { parent: null } );
this.model.destroy();
}
// And so on...
});
这篇关于在创建嵌套骨干型号骨干关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!