灰烬 - 了解反向关系

时间:2014-09-05 20:27:36

标签: ember.js

在阅读了Ember的页面上的Getting Started指南之后,我仍然有点混淆了什么是反向关系,以及何时定义它们。我知道你可能需要在定义相同类型的多个关系时使用它们,但我发现这个例子非常不清楚。这是来自文档的示例:

var belongsTo = DS.belongsTo,
    hasMany = DS.hasMany;

App.Comment = DS.Model.extend({
  onePost: belongsTo('post'),
  twoPost: belongsTo('post'),
  redPost: belongsTo('post'),
  bluePost: belongsTo('post')
});


App.Post = DS.Model.extend({
  comments: hasMany('comment', {
    inverse: 'redPost'
  })
});

在这个例子中,为什么redPost被选为反向而不是其他类型的帖子?如何将redPost定义为反差,将其与其余部分区分开来?我也真的不明白为什么评论会有多个帖子,只会增加我的困惑。

1 个答案:

答案 0 :(得分:66)

首先,this帖子可能会解释一些事情。这不是你的确切问题,但答案的原因是相似的。

但是,为了清楚地了解反转是什么,你应该熟悉directed graphs。虽然不是很明显,但有针对性的图表正在推动belongsTohasMany背后的理念。

但让我们回到具体细节。让我们以他们为榜样,只消除一些东西,使其更加真实。

App.Post = DS.Model.extend({
    comments: DS.hasMany('comment', { inverse: 'post' })
});

App.Comment = DS.Model.extend({
    post: DS.belongsTo('post', { inverse: 'comments' })
});

这是一个更真实的例子。每个帖子可以有任意数量的评论,而评论必须属于一个帖子。说得通。如您所见,这些反转是相互引用的。但是反过来又是什么呢?反向关系仅描述了在另一侧调用两个节点之间的边缘。例如,看看这张图片:

enter image description here

您将看到两个节点之间有一条边。从Post对象的角度来看,边缘称为comments。如果您希望通过该边缘连接节点,可以调用post.get('comments')。但是从Comment对象的角度来看,边缘被称为post。如果您想使用Comment对象通过该边缘连接节点,则必须调用comment.get('post')。这是反过来的。它描述了不同对象如何引用相同的关系。不同的名字,相同的边缘。通过明确声明反向,您可以告诉一个对象其他对象调用边缘的内容。

为什么这很重要?好吧,Ember-Data需要知道这样才能回报关系。例如,假设您有以下代码:

var post = store.find('post', '1');
var newComment = store.createRecord('comment', {});

...

post.get('comments').addObject(newComment);

您所做的是创建新评论并将其连接到现有的帖子对象。一个简单的用例。但是有一个问题:你只是告诉帖子有关评论,反之亦然。你告诉帖子你已经连接了评论,但你没有告诉评论你把它连接到帖子。但作为用户,您希望这两者同时发生。嗯,他们这样做,那是因为Ember-Data为你做到了。使用反向关系的名称,Ember-Data确保当您执行一个时,另一个也会发生。当你这样做时:

post.get('comments').addObject(newComment);
在幕后,Ember-Data真的这样做了:

post.get('comments').addObject(newComment);
newComment.set('post', post);

是Ember-Data需要反向关系的原因:所以它可以保持完整性,而不必担心它。