2014-09-05 99 views
25

在阅读完Ember页面上的Getting Started指南后,我仍然有点困惑,究竟什么是反向关系,以及何时定义它们。我知道在定义同一类型的多个关系时,您可能需要使用它们,但我发现该示例非常不清楚。这是从文档样本:Ember - 了解反向关系

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定义为与其余部分不同的区别?我也不明白为什么评论会有多个帖子,只会增加我的困惑。

回答

51

首先,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); 

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

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

灰烬,数据显示,在幕后,真正做到这一点:

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

就是为什么灰烬,数据所需要的反比关系:所以它可以保持完整无你不必担心。

+9

现在完全了解它 - 非常感谢。我认为Ember文档可以使用更好的例子。 – ncksllvn 2014-09-08 17:34:29

+0

很好的解释 – sarmahdi 2017-08-17 21:45:17