我一直在尝试遵循这里的示例:使用backboneJS + backbone-relational + requireJS创建嵌套模型
最后得到了一些不同的东西(因为我需要一个骨干)。集合,不是一个Backbone.RelationalModel):
define(['exports', 'backbone', 'backbone.relational'], function (Exports, Backbone) {
var ModuleModel = Backbone.RelationalModel.extend({
relations : [{
type : Backbone.HasMany,
key : "children",
relatedModel : 'ModuleModel',
collectionType : 'ModuleCollection'
}]
});
Exports.ModuleModel = ModuleModel;
return ModuleModel;
});
define(['exports', 'backbone'], function(Exports, Backbone) {
var ModuleCollection = Backbone.Collection.extend({
model : Exports.ModuleModel,
});
Exports.ModuleCollection = ModuleCollection;
return ModuleCollection;
});
但是,当我这样做的时候:
var modules = new ModuleCollection();
modules.fetch();
我:
TypeError: this.model is undefined
这是很明显的,因为出口。 ModuleCollection初始化后,创建ModuleModel。
关于如何实现这个自引用模型有什么提示吗?
提前感谢!
AMD的优点之一是它消除了对全局变量的需求,从而减少了查找对象引用所需的时间。所以,把对象放到全局命名空间绝对不是AMD:p
你原来的帖子中的主要问题似乎源于对RequireJS的误解。我看到了三个(也许四个)问题:
- 两个模块都不声明对另一个模块的引用(它们只引用Backbone和Backbone-relational)。
-
exports
似乎被用作全局命名空间的替代品-它不是。您使用exports
为模块创建一个空对象,该对象可立即供其他模块引用- ,但您必须引用它! -
relatedModel
和collectionType
接受对象引用或通过全局命名空间可访问的对象名称。由于使用的是AMD,所以没有定义全局变量,因此需要提供有效的对象引用。-
collectionType
将简单地指向导入的Collection
对象 -
relatedModel
有点棘手。因为它是一个自我引用,它引用的对象在extend()
操作完成之前实际上并不存在,所以你必须延迟它的赋值,直到以后。
-
- RequireJS要求每个文件只定义一个模块。我假设上面的代码示例代表两个独立的文件,但如果它们不是,它们应该。
这个应该可以工作:
ModuleModel.js:
define(['exports', 'ModuleCollection'], function (exports, Module) {
'use strict';
var Model = Backbone.RelationalModel.extend({
relations : [{
type : Backbone.HasMany,
key : 'children',
// `Model` undefined at this point in time, so this line is useless:
relatedModel : Model,
// `Collection` is attached to the imported `Module` object:
collectionType : Module.Collection
}]
});
// Now that `Model` is defined, we can supply a valid object reference:
Model.prototype.relations[0].relatedModel = Model;
// Attach `Model` to `exports` so an obj ref can be obtained elsewhere
exports.Model = Model;
});
ModuleCollection.js
define(['exports', 'ModuleModel'], function(exports, Module) {
'use strict';
var Collection = Backbone.Collection.extend({
// `Model` is attached to the imported `Module` object
model : Module.Model,
url: 'data.php' // <-- or wherever
});
// Attach `Collection` to `exports` so an obj ref can be obtained elsewhere
exports.Collection = Collection;
});
Main.js
define(['ModuleCollection'], function(Module) {
'use strict';
var modules = new Module.Collection();
modules.fetch();
});
好的,我通过在全局作用域中暴露命名空间(只是删除了var
)来解决这个问题。
我不知道这是不是AMD的投诉,但至少它看起来没有那么糟糕:
define(['backbone', 'backbone.relational'], function (Backbone) {
ModuleModel = Backbone.RelationalModel.extend({
relations : [{
type : Backbone.HasMany,
key : "children",
relatedModel : 'ModuleModel',
collectionType : 'ModuleCollection'
}]
});
return ModuleModel;
});
define(['backbone', 'models/module'], function(Backbone, ModuleModel) {
ModuleCollection = Backbone.Collection.extend({
model : ModuleModel,
});
return ModuleCollection;
});
如果有人有更好的解决方案,请随意发布!