Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用主干关系数据库在主干中创建嵌套模型_Javascript_Backbone.js_Backbone Relational - Fatal编程技术网

Javascript 使用主干关系数据库在主干中创建嵌套模型

Javascript 使用主干关系数据库在主干中创建嵌套模型,javascript,backbone.js,backbone-relational,Javascript,Backbone.js,Backbone Relational,我希望在我的应用程序中使用嵌套模型 我已经能够按照文档中的示例创建嵌套对象(例如一对多关系)。但是,我不知道如何以更新上层对象的方式绑定下层元素。我认为一个实用的应用程序将是一个非常有用的教程 因此,我的问题是:如何使用主干关系扩展,以便: 可以为每个项目添加/删除子项目 双击任何子项都会对其进行编辑(就像最初的Todo示例一样) 单击项目可隐藏/显示其子项目 子项不是单独获取的,只是Todo项的数组属性 更新:我有。到目前为止,我已经: 导入了上面提到的Todo示例 创建了一个Todos

我希望在我的应用程序中使用嵌套模型

我已经能够按照文档中的示例创建嵌套对象(例如一对多关系)。但是,我不知道如何以更新上层对象的方式绑定下层元素。我认为一个实用的应用程序将是一个非常有用的教程

因此,我的问题是:如何使用
主干关系扩展
,以便:

  • 可以为每个项目添加/删除子项目
  • 双击任何子项都会对其进行编辑(就像最初的Todo示例一样)
  • 单击项目可隐藏/显示其子项目
  • 子项不是单独获取的,只是Todo项的数组属性
更新:我有。到目前为止,我已经:

  • 导入了上面提到的Todo示例
  • 创建了一个
    TodosBitem
    模型和一个
    TodosBitemList
    集合
  • Todo
    模型更改为扩展
    RelationalModel
    而不是
    model
    ,其中
    todousibitem
  • 在html代码中添加了一个子项模板
但我仍然不知道如何:

  • 子项添加一个输入字段,该字段仅在单击
    Todo
    div时显示
  • 将子项数据作为
    Todo
    对象的属性,但仍有
    todosBitemView
    将DOM元素绑定到它们(例如
  • 标记)

在这种情况下,我不认为我会创建一个单独的“TODOUSIBITEM”——为什么不创建一个与Todo->Todo有很多关系的
,这样一个Todo就可以有0..*
子对象
,以及0..1
父对象

通过这种方式,您可以重复使用顺序逻辑(如果您将其更改为“应用于每个集合”),可以根据需要创建更深的嵌套级别(或者将其限制到某个深度,如果您愿意的话),等等。但是,为了适应这一点,需要更新许多内容-例如,保留一个子视图列表,这样您就可以对它们进行循环,将每个视图标记为已完成,并根据
TodoList
维护(和更新)顺序

无论如何,一个可能的解决方案的大致轮廓可以让您开始,作为与当前版本的一种区别(抱歉,它完全未经测试,因此可能包含可怕的错误):

//我们的基本**Todo**模型有'text'、'order'和'done'属性。
window.Todo=Backbone.RelationalModel.extend({
关系:[{
类型:Backbone.HasMany,
关键词:“儿童”,
相关模型:“待办事项”,
collectionType:“TodoList”,
反向关联:{
键:'父',
includeInJSON:“id”
}
}],
初始化:函数(){
if(!this.get('order')&&this.get('parent')){
set({order:this.get('parent').nextChildIndex()});
}
},
//todo项目的默认属性。
默认值:函数(){
返回{done:false};
},
//切换此待办事项的“完成”状态。
切换:函数(){
this.save({done:!this.get(“done”)});
}
nextChildIndex:function(){
var children=this.get('children');
返回children&&children.length | 0;
}
});
//todo项目的DOM元素。。。
window.TodoView=Backbone.View.extend({
//…是一个列表标记。
标记名:“li”,
//缓存单个项的模板函数。
模板:35;.template($('#项模板').html()),
//特定于项的DOM事件。
活动:{
“单击”:“切换子项”,
'按键输入.添加子项':'添加子项',
“单击。检查”:“切换完成”,
“dblclick div.todo-text”:“编辑”,
“单击span.todo销毁”:“清除”,
“按键。待办事项输入”:“更新输入”
},
//TodoView侦听对其模型的更改,然后重新渲染。
初始化:函数(){
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={};
},
//重新呈现todo项的内容。
render:function(){
html(this.template(this.model.toJSON());
这个.setText();
//当然,您可能想将其添加到模板中
this.el.append(“
    ”,{class':'children'}).append(“”,{type:'text',class':'addchild'}); _.each(this.get('children')、函数(child){ 这个.renderChild(child); },这个); 归还这个; }, addChild:函数(文本){ 如果(e.keyCode==13){ var text=this.el.find('input.add child').text(); var child=newtodo({parent:this.model,text:text}); } }, renderChild:函数(模型){ var childView=newtodoview({model:model}); this.childView[model.cid]=childView; this.el.find('ul.children').append(childView.render()); }, toggleChildren:function(){ $(this.el).find('ul.children').toggle(); }, //切换模型的“完成”状态。 toggleDone:function(){ this.model.toggle(); _.each(this.childview,function(child){ child.model.toggle(); }); }, 清除:函数(){ this.model.set({parent:null}); this.model.destroy(); } //等等。。。 });
我认为您无法在主干关系中创建自相关模型(如本文中的另一个答案所述)。当我尝试这一点时,我得到了一个错误:主干关系需要先定义relatedModel,然后才能创建与它的关系

所以,我修改了ma
//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...
});
Person = Backbone.RelationalModel.extend({
relations: [
    {
        type: 'HasMany',
        key: 'Children',
        relatedModel: 'FamilyRelation',
        reverseRelation: {
            key: 'Childrenof'
        }
    },
    {
        type: 'HasMany',
        key: 'Parent',
        relatedModel: 'FamilyRelation',
        reverseRelation: {
            key: 'Parentof'
        }
    }
]
});
// FamilyRelation is link model between two "Person"s 
// to achieve the Fan/Admiree relation.

FamilyRelation = Backbone.RelationalModel.extend({
})
KingKong = new Person({name: 'KingKong'});
SonOfKong = new Person({name: 'SonOfKong'});
KingKong.get("children").add({"parentof":SonOfKong});
var theModel = Backbone.RelationalModel.extend({ [...] });
theModel.prototype.relations.push({
  type: Backbone.HasOne,
  key: 'key',
  relatedModel: theModel
});