我是BackboneJS的新手,我使用带有RequireJS的Backbone关系模型的嵌套关系 - 我想我遇到了循环问题。任何帮助将受到高度赞赏!
我有以下型号和系列:
/* Module Model at models/module*/
define([
'jquery',
'underscore',
'backbone',
'backboneRelational',
], function($, _, Backbone) {
var ModuleModel = Backbone.RelationalModel.extend({
urlRoot: 'api/module',
_radius: 50,
relations: [{
type: Backbone.HasMany,
key: 'children',
relatedModel: 'ModuleModel',
collectionType: 'ModuleCollection',
reverseRelation: {
key: 'parent_id',
includeInJSON: 'id'
}
}],
url: function() {
return this.id? 'api/module/' + this.id : 'api/module';
}
});
return ModuleModel;
});
/* Module Collection */
define([
'jquery',
'underscore',
'backbone',
'models/module'
], function($, _, Backbone, ModuleModel) {
var ModuleCollection = Backbone.Collection.extend({
model: ModuleModel,
url: 'api/modules'
});
return ModuleCollection;
});
初始化对象ModuleModel时,会抛出以下错误:
Relation=child; no model, key or relatedModel (function (){ parent.apply(this, arguments); }, "children", undefined)
你能指出我正确的方向吗?
答案 0 :(得分:4)
这看起来像是一个范围问题。在初始化ModuleModel
期间,它想要与自己创建一个hasMany
关系,但它找不到自己,它会让你感到悲伤:
一旦从当前范围可以访问该对象,就会开始解决问题:
一种可能的解决方案是为模型和集合提供自己的命名空间,这可以从当前范围到达。
希望这有帮助。
答案 1 :(得分:3)
我从这里遇到了这个问题: RequireJS + BackboneRelational + Self-Referential。他似乎从这个帖子中继承了他的一些问题,所以我想我可能会增加我的一角钱。
首先,由于您使用的是RequireJS,因此没有全局变量。您不能简单地提供对象的名称,您需要提供relatedModel
和collectionType
的实际对象引用。
您最棘手的问题是,ModuleModel
的{{1}}实际上是relatedModel
本身,当您将其分配给ModuleModel
时将不会定义(使用AMD模型) )。您必须推迟分配,直到分配relatedModel
为止。
最后,您需要解决循环引用。 dokkaebi在建议使用ModuleModel
时走在正确的轨道上,但他的实施实际上误用了exports
。导出时,按照他的建议将对象直接附加到exports
,但是当您导入它时,您需要引用该模块以使用它,而不是exports
。
这应该有效:
<强> ModuleModel.js 强>
exports
<强> ModuleCollection.js 强>
define(['exports', 'ModuleCollection'], function (exports, Module) {
'use strict';
var ModuleModel = Backbone.RelationalModel.extend({
urlRoot: 'api/module',
_radius: 50,
relations: [{
type: Backbone.HasMany,
key: 'children',
// ModuleModel is undefined; this line is useless
// relatedModel: ModuleModel,
// no globals in require; must use imported obj ref
collectionType: Module.Collection,
reverseRelation: {
key: 'parent_id',
includeInJSON: 'id'
}
}],
url: function() {
return this.id? 'api/module/' + this.id : 'api/module';
}
});
// Now that `ModuleModel` is defined, we can supply a valid object reference:
ModuleModel.prototype.relations[0].relatedModel = ModuleModel;
// Attach `Model` to `exports` so an obj ref can be obtained elsewhere
exports.Model = ModuleModel;
});
<强> Main.js 强>
define(['exports', 'ModuleModel'], function(exports, Module) {
'use strict';
var ModuleCollection = Backbone.Collection.extend({
// must reference the imported Model
model: Module.Model,
url: 'data.php' // <-- or wherever
});
// Attach `Collection` to `exports` so an obj ref can be obtained elsewhere
exports.Collection = ModuleCollection;
});
答案 2 :(得分:2)
来自backbone-relational.js v0.5.0(第375行)的评论:
//'exports'应该是全局对象,如果以字符串形式给出,可以找到'relatedModel'。
如果在define调用中需要特殊的“exports”值作为依赖项,然后在返回之前将模块放在exports对象上,则可以将该模块作为字符串或导出成员引用。 / p> 在ModuleModel.js中
:
define(['exports', 'use!backbone', 'use!backbone-relational'], function(exports, Backbone) {
var ModuleModel = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasMany,
key: 'groups',
relatedModel: 'ModuleModel',
collectionType: 'ModuleCollection'
}
]
});
exports.ModuleModel = ModuleModel;
return ModuleModel;
});
并在ModuleCollection.js中:
define(['exports', 'use!backbone'], function(exports, Backbone) {
var ModuleCollection = Backbone.RelationalModel.extend({
url: '/api/v1/module/';
model: exports.ModuleModel;
});
exports.ModuleCollection = ModuleCollection;
return ModuleCollection;
});
答案 3 :(得分:2)
我回过头来遇到了同样的问题,然后按照Andrew Ferk用来提出问题的方法:Backbone-relational submodels with RequireJS。之所以出现这个问题,是因为您将模型定义为需求模块,因此它们不会存在于全局范围内,而骨干关系可以在其中查找它们。您可以使用addModelScope()来定义模型的范围,并告诉骨干关系在其中查找模型,而不是使用全局范围(超出Require的目的)或导出(对关系有点棘手)。 / p>
//modelStore.js - A scope in which backbone-relational will search for models
//Defined separately so you can access 'modelStore' directly for your models instead of requiring 'app' every time.
define(['app'], function(app) {
app.modelStore = {};
Backbone.Relational.store.addModelScope(app.modelStore);
return app.modelStore;
}
顺便说一句,你应该使用Backbone依赖,而不需要jQuery和Underscore。
//ModuleModel (The ModuleModel module. Nice.)
define(['modelStore', 'backbone', 'backboneRelational'], function(modelStore, Backbone {
modelStore.ModuleModel = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasMany,
key: 'groups',
relatedModel: 'ModuleModel', //Not modelStore.ModuleModel
collectionType: 'ModuleCollection'
}
]
});
return modelStore.ModuleModel;
});
现在有点迟到了,但希望它有助于其他人。