首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Backbone js +需要js + backbone关系+循环依赖+自引用

Backbone js +需要js + backbone关系+循环依赖+自引用
EN

Stack Overflow用户
提问于 2014-01-17 08:02:17
回答 2查看 991关注 0票数 2

我最近遇到了Backbone的问题,需要JS,因为我们有一个相当复杂的数据模型,我需要表示它导致了循环依赖和自我引用的问题。我在网上读了很多帖子(没有一个是真正有效的),但我想我找到了一个解决方案。因此,我想分享这一点,希望它能帮助经历过这个问题的人,但也要问你们,如果你们认为有办法解决问题。

第一个问题是,我的模型引用了引用集合的集合,而这些集合引用了引用集合的模型,所有这些都创建了一个混乱的循环依赖。坦率地说,这只是破坏了应用程序。下面是一个psuedo代码示例:

代码语言:javascript
复制
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 C

Backbone docs指出,这可以通过执行以下操作来实现:

代码语言:javascript
复制
  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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
define(["backbone", "libs/orca"], function(Backbone, Orca) {
  "use strict";

  Orca.Relational.CollectionA = Backbone.Collection.extend({});
});

models/a.js

代码语言:javascript
复制
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很相似,所以为了简短起见,我省略了它们。

要演示自我引用,请执行以下操作:

代码语言:javascript
复制
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依赖项引用。有没有更好的方法来做这件事?

EN

回答 2

Stack Overflow用户

发布于 2014-01-21 12:49:05

我实际上已经停止使用Backbone Relational,现在我使用JJRelational,因为它允许多对多关系。我还创建了一个名为"relational.js“的新文件来引用集合和模型,并将它们作为对象的属性返回,从而消除了从主应用程序文件中引用集合和模型的需要。这样,如果我需要一个新的模型或集合,我只需要"relational.js“。

我的relational.js文件看起来有点像这样:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
define(["libs/relational"], function(Relational){
  var broadcast = new Relational.Broadcast();
});
票数 1
EN

Stack Overflow用户

发布于 2014-01-17 13:32:05

你有没有推荐过Backbone Associations。我建议你看一看。

当我使用它的时候,我遇到过类似的循环依赖和自我引用问题。原因是我已经将客户端的Models映射到后端的Beans,这是使用Hibernate映射到Tables的。当您在Hibernate中指定one-to-many关系时,您需要指定一个实体到另一个实体的引用,反之亦然。然后,当这些实体由Jersey服务返回时,到JSON的转换具有循环依赖关系。我可以使用some annotations在后端摆脱它。但是没有办法在Backbone端解决这个问题。我向Backbone Associations的作者提出了这个问题,他们解决了这个问题。

希望这在某种或其他方面是有帮助的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21175440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档