javascript - 基于键的主干关系定义的正确方法

标签 javascript backbone.js backbone-relational

我已经看过文档好几次了,但我仍然不清楚这方面。我认为 Backbone 关系完全有可能做一些它没有做的事情。

我正在寻找基于键定义关系的方法,以避免所有样板文件都在胡说八道。

以规范的艺术家和专辑为例: 一个艺术家有很多专辑,由 album.artist_id 定义

/api/artist/62351 可能会返回

{
  id: 62351,
  name:"Jimi Hendrix"
}

同样/api/album?artist_id=62351 可能会返回

[
 {
   id:5678,
   name: "Are You Experienced?"
   artist_id: 62351
 },
 {
   id: 4321,
   name: "Axis: Bold as love",
   artist_id: 62351
 }
]

我如何定义艺术家和专辑的关系

var hendrixInstance = new Artist({id:62351});
hendrixInstance.get('albums');

会根据专辑 foreign_key artist_id 获取并返回专辑集合吗?它必须只是我尚未尝试的 key/keySource/keyDestination 的一些排列,或者是 backbone-relational 没有试图解决的问题,但我的 doc groking 失败了,我认为对此有一个简洁的答案SO 可能会对 future 的 Google 员工有所帮助。

var Artist = Backbone.RelationalModel.extend({
  urlRoot: '/api/artist',
  relations:[{
    key: 'albums', //Docs say this is the foreign key name, but in practice it doesn't appear that way. Need keySource/Destination?
    type: Backbone.HasMany,
    reverseRelation: {
      key: 'artist',
      type: Backbone.HasOne
    }
  }]
});
var Album = Backbone.RelationalModel.extend({
  urlRoot: '/api/album'
});

奖金指向一个示例模型,该模型使用 parent_id 引用其自身邻接列表样式

最佳答案

所以,@xzhang 上面的方法让我一直在迭代这个问题。首先,我很乐意在这方面被证明是错误的,但我还没有找到一种无需额外自定义代码的主干关系处理此问题的方法。由于在我看来这是 OneToMany 关系的一个令人难以置信的基本示例,所以我仍然抱有希望,我只是没有得到一些明显的东西。

这是我最终处理这种情况的方法。不幸的是,当调用 someobject.fetch('somerelationship') 时它仍然不会自动从服务器获取,这正是我真正想要的。 parse 函数对大多数人来说不是必需的,但它是我正在调用的 api 所必需的。

首先,我设置了一个基础集合,从中进行扩展:

  var BaseCollection = Backbone.Collection.extend({
    initialize: function(models, options) {
      if (_.isObject(options.relation)) {
      this.url = '/api/'
        + options.relation.keySource
        + '?search.'+options.relation.reverseRelation.keySource
        + '=' + options.foreignId;
      }
    },
    parse: function(res) { return res.success ? res.list : res },
  });

然后是一个可重用的辅助函数(可能会被整合到 BaseCollection 中)来帮助创建关系

  function collectionOptions(instance) {
    return {"relation":this, "foreignId":instance.get('id') };
  };

最后,这些关系被告知使用 BaseCollection 作为它们的 CollectionType,并且分配 collectionOptions() 助手来设置 collectionOptions。

 var Form = BaseModel.extend({
    urlRoot: '/api/form',
    relations:[
      {
        key: 'fills',
        keySource: 'fill',
        relatedModel: Fill,
        type: Backbone.HasMany,
        collectionOptions: collectionOptions,
        collectionType: BaseCollection,
        reverseRelation: {
          key: 'form',
          keySource: 'form_id',
          type: Backbone.HasOne
        }
      },{
        key: 'children',
        keySource: 'form',
        relatedModel: 'Form',
        type: Backbone.HasMany,
        collectionOptions: collectionOptions,
        collectionType: BaseCollection,
        reverseRelation: {
          key: 'parent',
          keySource: 'parent_id',
          type: Backbone.HasOne
        }
      }
    ]
  });

这使我能够避免更改服务器端 API 以返回 ID 列表,然后单独获取这些 ID。相反,我可以:

var form = new Form({id:1});
form.get('children').fetch();
form.toJSON(); //now has {id:1, ..., ..., children:[child,child,child,...]}

在第一次调用 .get('children') 时对 autoFetch children 的扩展只是问题所在,但我还没有发现如何在不修改 backbone-relational 本身的情况下做到这一点。

关于javascript - 基于键的主干关系定义的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15977170/

相关文章:

backbone.js - Backbone 关系不设置父模型,或反向关系_id

javascript - jquery绑定(bind)点击事件到ui slider

javascript - Backbone Relational 没有正确设置反向关系?

backbone.js - _.bindAll(this) 和 Uncaught TypeError : Cannot read property 'idAttribute' of undefined in backbone-relation. js

unit-testing - 使用RequireJS(和Jasmine/Sinon)时如何 stub 在另一个 View 渲染方法中实例化的主干 View

javascript - jsPlumb 最好的 javascript MVC 框架

javascript - 类型错误 : 'undefined' is not an object in Javascript

javascript - 用于复制图像的 Firefox WebExtension 替代插件剪贴板 sdk

同一行上用于定义 CSS 值的 JavaScript 速记数学

javascript - 仅使用 javascript 替换损坏的图像