使用 Backbone.js JS+ Backbone.js 关系型+ requireJS创建嵌套模型

trnvg8h3  于 2022-11-10  发布在  其他
关注(0)|答案(4)|浏览(229)

我是一个新的BackboneJS和我坚持与嵌套关系使用 Backbone 关系模型与RequireJS -我想我遇到了循环问题。任何帮助将不胜感激!
我有以下型号和系列:

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

你能给我指一下正确的方向吗?

ve7v8dk2

ve7v8dk21#

这看起来像是一个作用域问题。在ModuleModel的初始化过程中,它想创建一个与自身的hasMany关系,但是它找不到自己,它会以上述错误的形式给你带来麻烦:
http://jsfiddle.net/yNLbq
一旦对象可以从当前作用域访问,事情就开始解决了:
http://jsfiddle.net/jDw5e
一个可能的解决方案是为模型和集合提供一个可以从当前作用域访问的命名空间。
希望这对你有帮助。

qnakjoqk

qnakjoqk2#

我从这里遇到了这个问题:RequireJS + BackboneRelational + Self-Referential .他似乎从这个线程继承了他的一些问题,所以我想我可能会添加我的一角硬币。
首先,因为使用的是RequireJS,所以没有全局变量,不能简单地提供对象的名称,需要提供relatedModelcollectionType的实际对象引用。
最棘手的问题是ModuleModelrelatedModel实际上是ModuleModel本身,当你把它赋值给relatedModel(使用AMD模型)时,它不会被定义。你必须推迟赋值,直到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);
      });
    });

});
z6psavjg

z6psavjg3#

来自backbone-relational.js v0.5.0中的一条注解(第375行):
// 'exports'应该是全域对象,如果指定为字串,则可以在其中找到'relatedModel'。
如果您需要特殊的'exports'值作为define调用中的依赖项,然后在返回之前将模块放在exports对象上,那么您可以将该模块作为字符串或exports的成员引用。
在模块模型.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;
});
pb3skfrl

pb3skfrl4#

不久前,我遇到了同样的问题,并采用了安德鲁·弗克(Andrew Ferk)提出问题时所用的方法:Backbone-relational submodels with RequireJS。问题的出现是因为您将模型定义为Require模块,这样它们就不存在于全局作用域中,而backbone-relational可以在全局作用域中查找它们。您可以使用addModelScope()为模型定义一个作用域,并告诉backbone-relational在其中查找模型,而不是使用全局作用域(比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.js 依赖项,而不需要为它要求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;
});

现在说这个有点晚了,但希望它能帮助其他人。

相关问题