我最近遇到了Backbone的问题,需要JS,因为我们有一个相当复杂的数据模型,我需要表示它导致了循环依赖和自我引用的问题。我在网上读了很多帖子(没有一个是真正有效的),但我想我找到了一个解决方案。因此,我想分享这一点,希望它能帮助经历过这个问题的人,但也要问你们,如果你们认为有办法解决问题。
第一个问题是,我的模型引用了引用集合的集合,而这些集合引用了引用集合的模型,所有这些都创建了一个混乱的循环依赖。坦率地说,这只是破坏了应用程序。下面是一个psuedo代码示例:
Model A
has Collection B
Collection B
of Model B
Model B
has Collection A
has Collection C
Collection A
of Model A
Collection C
of Model CBackbone docs指出,这可以通过执行以下操作来实现:
initialize: function() {
this.messages = new Messages;
this.messages.url = '/mailbox/' + this.id + '/messages';
this.messages.on("reset", this.updateCounts);
},我尝试了各种方法来解决我们的需求,但我们复杂的嵌套要求打破了地狱的骨干。因此,我偶然发现了backbone relational,并为我们的数据模型创建了一个基本的工作表示(这涉及到创建一个填充程序来使用Require )。从本质上讲,这是可行的。因此,我扩展了该示例,以便模型C也可以具有集合C的实例(自引用)。这似乎又一次起到了作用。太棒了。然而,将这个示例应用到我的应用程序中要困难得多--将模型和集合拆分成单独的文件更加困难,因为backbone relational希望集合和模型名称位于全局名称空间中(使用Require和"use strict“有点棘手)。由于我们的复杂数据模型,我希望使用字符串标识符来表示关系以进行前向引用,而不是显式的请求引用,事实证明这也很困难。我尝试将所有内容添加到exports名称空间,但同样不起作用。无论如何,我想我已经找到了一个解决方案,将集合和模型添加到自定义命名空间,然后将此命名空间添加到backbonerelational模型作用域。我已经将我的定制库命名为"Orca“(因为虎鲸实在太棒了)。
bootstrap.js
require.config({
paths: {
"jquery" : "../bower_components/jquery/jquery",
"underscore" : "../bower_components/underscore-amd/underscore",
"backbone" : "../bower_components/backbone-amd/backbone",
"relational" : "../bower_components/backbone-relational/backbone-relational",
...
shim: {
"underscore": {
exports: "_"
},
"backbone": {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
"relational": {
deps: ["backbone"]
},
...app.js
define(["backbone", "relational", "libs/orca", "collections/a", "models/a", "collections/b", "models/b", "collections/c", "models/c"], function(Backbone, Relational, Orca){
"use strict";
var App = function(options) {
this.initialize(otions);
};
App.prototype = _.extend(Backbone.Events, {
initialize: function(options) {
Orca.initialize();
var a = new Orca.Relational.ModelA([],{});
}
}
return App;
});lib/orca.js
define(["backbone", "relational"], function(Backbone) {
"use strict";
var Orca = {
Relational: {},
initialize: function() {
Backbone.Relational.store.addModelScope(this.Relational);
}
};
// I actually extend Backbone.RelationalModel so I can have custom methods,
// e.g. "parse" but I've simplified the code for example's sake...
Orca.Model = Backbone.RelationalModel;
Orca.Collection = Backbone.Collection;
return Orca;
});collections/a.js
define(["backbone", "libs/orca"], function(Backbone, Orca) {
"use strict";
Orca.Relational.CollectionA = Backbone.Collection.extend({});
});models/a.js
define(["backbone", "libs/orca"], function(Backbone, Orca) {
"use strict";
Orca.Relational.ModelA = Orca.Model.extend({
relations: [
{
type: Backbone.HasMany,
key: "bs",
relatedModel: "ModelB",
includeInJSON: Backbone.Model.prototype.idAttribute,
collectionType: "CollectionB",
reverseRelation: {
key: "a"
}
}
]
});
});CollectionB和ModelB很相似,所以为了简短起见,我省略了它们。
要演示自我引用,请执行以下操作:
define(["backbone", "libs/orca"], function(Backbone, Orca) {
"use strict";
Orca.Relational.ModelC = Orca.Model.extend({
relations: [
{
type: Backbone.HasMany,
key: "cs",
relatedModel: "ModelC",
includeInJSON: Backbone.Model.prototype.idAttribute,
collectionType: "CollectionC",
reverseRelation: {
key: "c"
}
}
]
});
});所以我对这段代码的错误在于,我在app.js中创建了一个新的ModelA实例。但是,因为它引用了CollectionB,而ModelB又引用了集合C并使用了模型C,所以我必须将所有这些都作为require依赖项引用。有没有更好的方法来做这件事?
发布于 2014-01-21 12:49:05
我实际上已经停止使用Backbone Relational,现在我使用JJRelational,因为它允许多对多关系。我还创建了一个名为"relational.js“的新文件来引用集合和模型,并将它们作为对象的属性返回,从而消除了从主应用程序文件中引用集合和模型的需要。这样,如果我需要一个新的模型或集合,我只需要"relational.js“。
我的relational.js文件看起来有点像这样:
define([
// Models
"models/broadcast",
"models/version",
// Collections
"collections/broadcasts",
"collections/versions"
], function(
// Models
Broadcast,
Version,
// Collections
Broadcasts,
Versions
) {
"use strict";
var _relational = {
Broadcast: Broadcast,
Version: Version,
Broadcasts: Broadcasts,
Versions: Versions,
};
// Register the Collections
Backbone.JJRelational.registerCollectionTypes({
"Broadcasts": _relational.Broadcasts,
"Versions": _relational.Versions
});
// Provide JJRelational with model scope - pull request submitted to JJRelational to handle this
Backbone.JJStore.addModelScope(_relational);
return _relational;
});然后在我的主app.js中:
define(["libs/relational"], function(Relational){
var broadcast = new Relational.Broadcast();
});发布于 2014-01-17 13:32:05
你有没有推荐过Backbone Associations。我建议你看一看。
当我使用它的时候,我遇到过类似的循环依赖和自我引用问题。原因是我已经将客户端的Models映射到后端的Beans,这是使用Hibernate映射到Tables的。当您在Hibernate中指定one-to-many关系时,您需要指定一个实体到另一个实体的引用,反之亦然。然后,当这些实体由Jersey服务返回时,到JSON的转换具有循环依赖关系。我可以使用some annotations在后端摆脱它。但是没有办法在Backbone端解决这个问题。我向Backbone Associations的作者提出了这个问题,他们解决了这个问题。
希望这在某种或其他方面是有帮助的。
https://stackoverflow.com/questions/21175440
复制相似问题