10

私はBackboneJSを初めて使用し、RequireJSでBackbone-relationalModelを使用してネストされた関係で立ち往生しています-循環的な問題に遭遇したと思います。どんな助けでも大歓迎です!

私は次のモデルとコレクションを持っています:

 /* 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)

正しい方向に向けていただけませんか。

4

4 に答える 4

4

これはスコープの問題のようです。初期化中にそれ自体とModuleModelの関係を作成したいのhasManyですが、それ自体を見つけることができず、上記のエラーの形で悲しみを与えます:

http://jsfiddle.net/yNLbq

現在のスコープからオブジェクトに到達できるようになると、次のようになります。

http://jsfiddle.net/jDw5e

考えられる解決策は、モデルとコレクションに、現在のスコープから到達できる名前空間を与えることです。

お役に立てれば。

于 2012-05-09T08:47:14.130 に答える
3

ここからこの問題に遭遇しました: RequireJS + BackboneRelational + Self-Referential。彼はこのスレッドからいくつかの問題を受け継いでいるようです。

まず、RequireJS を使用しているため、グローバル変数はありません。オブジェクトの名前を単純に指定することはできません。 と の実際のオブジェクト参照を指定する必要がありrelatedModelますcollectionType

最も厄介な問題は、ModuleModelrelatedModel実際にはそれ自体であり、 (AMD モデルを使用して)ModuleModelに割り当てるときに定義されないことです。relatedModelが割り当てられるまで、割り当てを延期する必要がありModuleModelます。

最後に、循環参照を解決する必要があります。dokkaebi は を使用することを提案したときは正しい方向に進んでexportsいますが、彼の実装は実際には を誤用してexportsいます。エクスポートするときは、彼が提案するようにオブジェクトを直接アタッチしますexportsが、インポートするときは、ではなくモジュールを参照して使用する必要がありますexports

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

ModuleModel.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;
});

ModuleCollection.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;
});

Main.js

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

    var modules = new Module.Collection();
    modules.fetch().done(function() {
      modules.each(function(model) {
        console.log(model);
      });
    });

});
于 2013-06-09T01:06:23.800 に答える
2

backbone-relational.js v0.5.0 のコメント (375 行目) から:
// 'exports' は、文字列として指定された場合に 'relatedModel' が見つかるグローバル オブジェクトである必要があります。

define 呼び出しで依存関係として特別な 'exports' 値が必要な場合、そして戻る前にモジュールを exports オブジェクトに配置すると、そのモジュールを文字列または exports のメンバーとして参照できます。

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;
});
于 2012-06-08T22:26:15.277 に答える
2

私はしばらく前に同じ問題に遭遇し、Andrew Ferk が質問に対して使用したアプローチに従いました: RequireJS を使用したバックボーン リレーショナル サブモデル。モデルを Require モジュールとして定義しているため、バックボーンリレーショナルが検索できるグローバルスコープにモデルが存在しないため、問題が発生します。グローバル スコープ (Require の目的に勝る) やエクスポート (リレーションに関しては少しトリッキー) を使用する代わりに、モデルのスコープを定義し、addModelScope()を使用して backbone-relational にその中のモデルを探すように指示できます。

//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;
}

ちなみに、バックボーンの依存関係をシムする必要があり、jQuery とアンダースコアを必要とする必要はありません。

//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;
});

これはちょっと遅いですが、他の人に役立つことを願っています。

于 2014-04-19T17:55:09.220 に答える