最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I cleanly pull a Parse.Object relation's records when fetching the object? - Stack Overflow

programmeradmin0浏览0评论

In the Parse JavaScript guide, on the subject of Relational Data it is stated that

By default, when fetching an object, related Parse.Objects are not fetched. These objects' values cannot be retrieved until they have been fetched.

They also go on to state that when a relation field exists on a Parse.Object, one must use the relation's query().find() method. The example provided in the docs:

var user = Parse.User.current();
var relation = user.relation("likes");
relation.query().find({
  success: function(list) {
    // list contains the posts that the current user likes.
  }
});

I understand how this is a good thing, in terms of SDK design, because it prevents one from potentially grabbing hundreds of related records unnecessarily. Only get the data you need at the moment.

But, in my case, I know that there will never be a time when I'll have more than say ten related records that would be fetched. And I want those records to be fetched every time, because they will be rendered in a view.

Is there a cleaner way to encapsulate this functionality by extending Parse.Object?

In the Parse JavaScript guide, on the subject of Relational Data it is stated that

By default, when fetching an object, related Parse.Objects are not fetched. These objects' values cannot be retrieved until they have been fetched.

They also go on to state that when a relation field exists on a Parse.Object, one must use the relation's query().find() method. The example provided in the docs:

var user = Parse.User.current();
var relation = user.relation("likes");
relation.query().find({
  success: function(list) {
    // list contains the posts that the current user likes.
  }
});

I understand how this is a good thing, in terms of SDK design, because it prevents one from potentially grabbing hundreds of related records unnecessarily. Only get the data you need at the moment.

But, in my case, I know that there will never be a time when I'll have more than say ten related records that would be fetched. And I want those records to be fetched every time, because they will be rendered in a view.

Is there a cleaner way to encapsulate this functionality by extending Parse.Object?

Share Improve this question asked Sep 5, 2014 at 15:48 zealoushackerzealoushacker 6,9166 gold badges38 silver badges46 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Have you tried using include("likes")?

I'm not as familiar with he JavaScript API as the ObjC API.. so in the example below I'm not sure if "objectId" is the actual key name you need to use...

var user = Parse.User.current();
var query = new Parse.Query(Parse.User);
query.equalTo(objectId, user.objectId);
query.include("likes")
query.find({
  success: function(user) {
    // Do stuff
  }
});

In general, you want to think about reverse your relationship. I'm not sure it is a good idea be adding custom value to the User object. Think about creating a Like type and have it point to the user instead.

Example from Parse docs: https://parse./docs/js_guide#queries-relational

var query = new Parse.Query(Comment);

// Retrieve the most recent ones
query.descending("createdAt");

// Only retrieve the last ten
query.limit(10);

// Include the post data with each ment
query.include("post");

query.find({
  success: function(ments) {
    // Comments now contains the last ten ments, and the "post" field
    // has been populated. For example:
    for (var i = 0; i < ments.length; i++) {
      // This does not require a network access.
      var post = ments[i].get("post");
    }
  }
});

Parse.Object's {Parse.Promise} fetch(options) when bined with Parse.Promise's always(callback) are the key.

We may override fetch method when extending Parse.Object to always retrieve the relation's objects.

For example, let's consider the following example, where we want to retrieve a post and its ments (let's assume this is happening inside a view that wants to render the post and its ments):

var Post = Parse.Object.extend("Post"),
    postsQuery = new Parse.Query(Post),
    myPost;

postsQuery.get("xWMyZ4YEGZ", {
  success: function(post) {
    myPost = post;
  }
).then(function(post) {
  post.relation("ments").query().find({
    success: function(ments) {
      myPost.ments = ments;
    }
  });
});

If we had to do this every time we wanted to get a post and its ments, it would get very repetitive and very tiresome. And, we wouldn't be DRY, copying and pasting like 15 lines of code every time.

So, instead, let's encapsulate that by extending Parse.Object and overriding its fetch function, like so:

/*
  models/post.js
*/

window.myApp = window.myApp || {};

window.myApp.Post = Parse.Object.extend("Post", {
  fetch: function(options) {
    var _arguments = arguments;
    this.mentsQuery = this.relation("ments").query();
    return this.mentsQuery.find({
      success: (function(_this) {
        return function(ments) {
          return _this.ments = ments;
        };
      })(this)
    }).always((function(_this) {
      return function() {
        return _this.constructor.__super__.fetch.apply(_this, _arguments);
      };
    })(this));
  }
});

Disclaimer: you have to really understand how closures and IIFEs work, in order to fully grok how the above works, but here's what will happen when fetch is called on an existing Post, at a descriptive level:

  1. Attempt to retrieve the post's ments and set it to the post's ments attribute
  2. Regardless of the oute of the above (whether it fails or not) operation, always perform the post's default fetch operation, and invoke all of that operation's callbacks
发布评论

评论列表(0)

  1. 暂无评论