Ember - Understanding Inverse Relationships

前端 未结 1 1395
花落未央
花落未央 2020-12-25 11:41

After reading through the Getting Started guide on Ember\'s page, I\'m still a bit confused what exactly an inverse relationship is, and when to define them. I understand th

相关标签:
1条回答
  • 2020-12-25 12:16

    First of all, this post might explain things a bit. It's not your exact question, but the reasons for the answer are similar.

    But, to get a clear understanding of what inverses are, you should be familiar with directed graphs. While not immediately apparent, directed graphs are what fuel the idea behind belongsTo and hasMany.

    But let's get back to specifics. Let's take their example, only eliminate some stuff to make it more realistic.

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

    This is a more real world example. Each post can have any number of comments, while a comment must belong to exactly one post. Makes sense. As you can see, those inverses refer to each other. But what is an inverse? An inverse relationship just describes what the edge between two nodes is called on the other side. For example, look at this picture:

    enter image description here

    You'll see two nodes with a single edge between them. From the perspective of a Post object, the edge is called comments. If you wanted get the node connected by that edge, you could call post.get('comments'). But from the perspective of the Comment object, the edge is called post. If you wanted to get the node connected by that edge using the Comment object, you'd have to call comment.get('post'). That's what an inverse is. It describes how different objects refer to the same relationship. Different name, same edge. By explicitly declaring the inverse, you tell one object what the other object calls the edge.

    Why is that important? Well, Ember-Data needs to know that so it can reciprocate relationships. For example, let's say you have the following code:

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

    What you did is create a new comment and connect it to an existing post object. A simple enough use case. But there's one problem: you only told the post about the comment, not vice-versa. You told the post that you connected the comment, but you didn't tell the comment that you connected it to the post. But as a user, you expect those both to happen at the same time. Well, they do, and that's because Ember-Data does it for you. Using the names of the inverse relationship, Ember-Data ensures that when you do one, the other happens as well. When you do this:

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

    Ember-Data, behind the scenes, really does this:

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

    That is why Ember-Data needs the inverse relationship: so it can maintain integrity without you having to worry about it.

    0 讨论(0)
提交回复
热议问题