10

我是 BackboneJS 的新手,我被使用带有 RequireJS 的 Backbone-relational Model 的嵌套关系困住了——我想我遇到了循环问题。任何帮助将不胜感激!

我有以下模型和集合:

 /* 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,因此没有全局变量。您不能简单地提供对象的名称,您需要为relatedModeland提供实际的对象引用collectionType

ModuleModel你最棘手的问题是relatedModel实际上是它本身,当您将它分配给(使用 AMD 模型)ModuleModel时不会定义它。relatedModel您必须将分配推迟到分配之后ModuleModel

最后,您需要解决循环引用。dokkaebi 在他建议使用时是在正确的轨道上exports,但他的实现实际上滥用了exports。导出时,按照他的建议直接附加对象exports,但是导入时需要引用模块才能使用它,而不是exports.

这应该有效:

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

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

主.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

不久前我遇到了同样的问题,并遵循了 Andrew Ferk 用于他的问题的方法:Backbone-relational submodels with RequireJS。出现问题是因为您将模型定义为 Require 模块,因此它们不存在于全局范围内,骨干关系可以在其中查找它们。您可以使用addModelScope()为模型定义一个范围并告诉骨干关系在其中查找模型,而不是使用全局范围(超出 Require 的目的)或导出(关系有点棘手) 。

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

现在有点晚了,但希望它可以帮助其他人。

于 2014-04-19T17:55:09.220 回答
2

从backbone-relational.js v0.5.0(第375行)中的评论:
//'exports'应该是全局对象,如果以字符串形式给出,则可以在其中找到'relatedModel'。

如果您在定义调用中需要特殊的“导出”值作为依赖项,然后在返回之前将模块放在导出对象上,那么您可以将该模块作为字符串或导出的成员引用。

在 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 回答