0

私はここの例に従おうとしています:入れ子になったモデルを backboneJS + backbone-relational + requireJS で作成する

そして、最終的に何か違うものになりました(Backbone.RelationalModelではなくBackbone.Collectionが必要なので):

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 が初期化された後にExports.ModuleModel が作成されるため、これは明らかです。

この自己参照モデルを実現する方法に関するヒントはありますか?

前もって感謝します!

4

2 に答える 2

1

AMD の利点の 1 つは、グローバル変数が不要になるため、オブジェクト参照の検索に必要な時間が短縮されることです。つまり、オブジェクトをグローバル名前空間に配置することは、AMD ではないことは間違いありません :p

元の投稿の主な問題は、RequireJS の誤解に起因するようです。3 つ (おそらく 4 つ) の問題があります。

  1. どちらのモジュールも他方への参照を宣言しません (バックボーンとバックボーン リレーショナルのみを参照します)。
  2. exportsグローバル名前空間の代わりに使用されているように見えますが、そうではありません。exports他のモジュールからすぐに参照できるモジュール用の空のオブジェクトを作成するために使用しますが、それを参照する必要があります!
  3. relatedModelcollectionTypeオブジェクト参照またはグローバル名前空間を介してアクセス可能なオブジェクトの名前のいずれかを受け入れます。AMD を使用しているため、グローバルを定義していないため、有効なオブジェクト参照を提供する必要があります。
    • collectionTypeインポートされたCollectionオブジェクトを指すだけです
    • relatedModel少しトリッキーです。これは自己参照であるため、参照しているオブジェクトは操作が完了するまで実際には存在しないextend()ため、後で割り当てを遅らせる必要があります。
  4. RequireJS では、各ファイルが正確に 1 つのモジュールを定義する必要があります。上記のコード サンプルは 2 つの別個のファイルを表していると想定していますが、そうでない場合は、そうすべきです。

これはうまくいくはずです:

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();

});

お役に立てれば...

于 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 に答える