0

我一直在尝试遵循此处的示例:使用主干JS + 主干关系+ requireJS 创建嵌套模型

最后得到了一些不同的东西(因为我需要一个 Backbone.Collection,而不是 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

这很明显,因为 Exports.ModuleModel 是在 ModuleCollection初始化之后创建的。

关于如何实现这种自我参照模型的任何提示?

提前致谢!

4

2 回答 2

1

AMD 的优点之一是它消除了对全局变量的需要,从而减少了查找对象引用所需的时间。所以是的,将对象放在全局命名空间中绝对不是 AMD :p

您原始帖子中的主要问题似乎源于对 RequireJS 的误解。我看到三个(也许四个)问题:

  1. 两个模块都没有声明对另一个的引用(它们只引用 Backbone 和 Backbone-relational)。
  2. exports似乎被用作全局命名空间的替代品 - 它不是。您可以exports为模块创建一个空对象,该对象可立即供其他模块引用 -但您必须引用它!
  3. relatedModelcollectionType接受对象引用或可通过全局命名空间访问的对象名称。由于您使用的是 AMD,因此您没有定义全局变量,因此您需要提供有效的对象引用。
    • collectionType将简单地指向导入的Collection对象
    • relatedModel有点棘手。由于它是自引用,因此它所引用的对象在操作完成之前实际上并不存在extend(),因此您必须将其分配延迟到以后。
  4. RequireJS 要求每个文件只定义一个模块。我假设上面的代码示例代表两个单独的文件,但如果他们不这样做,他们应该这样做。

这应该有效:

模块模型.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;
});

模块集合.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;
});

主.js

define(['ModuleCollection'], function(Module) {
    'use strict';

    var modules = new Module.Collection();
    modules.fetch();

});

希望这可以帮助...

于 2013-06-09T00:35:22.093 回答
0

好的,我通过在全局范围内公开命名空间(刚刚删除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;
});

如果有人有更好的解决方案,请随时发布!

于 2013-06-03T13:33:52.083 回答