具有异步关系的Ember-Data store.filter

时间:2015-05-12 10:40:50

标签: ember.js ember-data

我正在开发一个调查应用程序,我们正在使用现有的API。我们的模型看起来像:

App.User = DS.Model.extend({
  name: DS.attr('string'),
  participations: DS.hasMany('participation', {async: true})
});

App.Participation = DS.Model.extend({
  user: DS.belongsTo('user', {async: true}),
  survey: DS.belongsTo('survey', {async: true}),
  hasCompleted: DS.attr('boolean'),
  hasAccepted: DS.attr('boolean')
});

App.Survey = DS.Model.extend({
  participations: DS.hasMany('participation', {async: true}),
  title: DS.attr('string'),
  locked: DS.attr('boolean')
});

我想通过store.filter从我的模型钩子返回一个实时记录数组,但是这个过滤器需要处理调查和当前用户的异步参与者记录。如何处理我的过滤器回调函数中的异步关系解析?

  model: function() {
    return Ember.RSVP.hash({
      user: this.store.find('user', 1),
      surveys: this.store.filter('survey', {}, function(survey) {
        return !survey.get('locked'); //How do I get the participation record for the current user for the current poll so I can also filter out the completed true
      })
    });
  }

如果使用实时记录数组调查不是最好的方法来处理这个问题是什么?

编辑: 我已经更新了尝试的方法:

App.SurveysRoute = Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      user: this.store.find('user', 1),
      all: this.store.find('survey'),
      locked: this.store.filter('survey', function(survey) {
        return survey.get('locked');
      }),
      completed: this.store.filter('participation', {user: 1}, function(participation) {
        return participation.get('hasCompleted');
      }),
      outstanding: this.store.filter('participation', {user: 1}, function(participation) {
        return !participation.get('hasCompleted') && !participation.get('poll.locked');
      })
    });
  }
});
App.SurveysCompletedRoute = Ember.Route.extend({
  model: function() {
    return this.modelFor('surveys').completed.mapBy('survey');
  }
});

http://jsbin.com/vowuvo/3/edit?html,js,output

但是,在我的过滤器中使用异步属性participation.get('poll.locked')是否会造成潜在问题?

1 个答案:

答案 0 :(得分:0)

最初用ES6和ember-cli格式编写了我的回复,同时对Ember引用进行了本地化...请原谅这是否为触摸基础,因为我将其恢复为ES5并使用了常用的Ember代码结构。

试试这个:

// beforeModel() and model() are skipped if coming from a collection
// ie: from '/users' to '/users/1'
// setting this up is purely for direct linking to this route's path.
model: function(params) {
    return this.store.findRecord('user', params.id).then(function(user) {
        return user.get('participations');
    });
},

// only fired once! 
// soon to be obsolete...
setupController: function(controller, model) {
    controller.set('model', model);

    var store  = this.store,
        userId, availSurveys, completed, outstanding;

    store  = this.store;
    userId = model.get('id');

    // this is a promise!
    // also, these filters can be applied elsewhere that Store is available!
    availSurveys = store.filter(
        // modelName to be filtered.
                    'surveys',
        // this part is the query - sent as a request to server, not used as a filter 
                    { locked: false },
        // this is the active filter that will be applied to all survey records in client, 
        // updating 'availSurveys' as the records change
                    function(survey) {
                        return !survey.get('locked');
                    });

    completed = store.filter('participation', 
                    { 
                        user         : userId,
                        hasCompleted : true
                    }, 
                    function(participation) {
                        return participation.get('hasCompleted');
                    });

    outstanding = store.filter('participation', 
                    { 
                        user         : userId,
                        hasCompleted : false,
                        survey       : { locked: false }
                    }, 
                    function(participation) {
                        // this is also a promise!
                        return participation.get('survey').then(function(survery) {
                            return !participation.get('hasCompleted') && !survey.get('locked');
                        });
                    });

    // alternatively, hashSettled waits until all promises in hash have resolved before continuing
    Ember.RSVP.hash({
        availSurveys : availSurveys,
        completed    : completed,
        outstanding  : outstanding
    }).then(function(hash) {
        controller.set('availSurveys', hash.availSurveys);
        controller.set('completed',    hash.completed);
        controller.set('outstanding',  hash.outstanding);
    });
}