Ember.js在父路由中对hasMany关系的子进行排序和过滤

时间:2013-01-30 09:57:28

标签: ember.js ember-data ember-router

更新#2

我发现当我重构过滤逻辑发生在PostController中的复合计算属性中而不是在单个路径中时,我能够让它工作。解决方案最终依赖于由特定的#linkTo路由操作设置的单个动态变量,该操作触发了PostController计算属性中的过滤更改。我有很多工作需要赶上,所以我现在无法将解决方案发布到这个具体问题,但是当我可以时,我将详细解释下面的解决方案。现在我已经将@ twinturbo的答案标记为正确的,因为他在下面给出了部分但非常有用的指导。再次感谢男人!!非常感激!!

更新#1

最新的小提琴是http://jsfiddle.net/aZNRu/14/和@ twinturbo的帮助,在其Post父控制器中对Comments的“rank”属性进行排序,以及基本过滤。仍然存在在过滤后的路线中无法获得自动更新视图以及创建新评论的问题。

原始问题

我看到了there is talk of combining the sortable mixin with filtering functionality,但就目前而言,正如您在jsfiddle example中看到的那样,我在排序和过滤方面遇到了问题:

1)我无法弄清楚如何按其父控制器中的特定子属性进行排序。如果我们有:

App.Post = DS.Model.extend({
    title: DS.attr('string'),
    post: DS.attr('string'),
    comments: DS.hasMany('App.Comment')
});

App.Comment = DS.Model.extend({
    post: DS.belongsTo('App.Post'),
    description: DS.attr('string'),
    isActive: DS.attr('boolean'),
    rank: DS.attr('number')
});

App.Router.map(function() {
  this.resource("posts", { path: "/" }, function() {
    this.resource('post', { path: ':post_id' }, function() {
        this.route('active');
        this.route('inactive');
     });
   });
});

我希望能够按照“rank”属性按升序对每个帖子的评论进行排序。我想做点什么:

App.PostController = Ember.ObjectController.extend({
    sortProperties: ['comments.rank']

但是对于一个,我认为sortProperties只适用于arrayControllers,我认为它不能超过一个级别。我怎么能做到这一点?

2)第二个问题是在过滤后的路线中没有获得自动更新视图。例如,如果您通过单击“活动注释”查看jsfiddle并进入活动过滤路径,则会对当前数据产生良好的过滤效果。但是,如果您保持活动路径并通过单击“添加新注释”创建一个处于活动状态的新记录,则该记录不会自动呈现在“活动”下,并且仅在您单击另一个路径然后返回到该路径时才会显示。

我是否在路线中错误地设置路线过滤或在模板中引用错误?

App.PostActiveRoute = Ember.Route.extend({
  setupController: function() {
    var post = this.controllerFor('post').get('model'),
    comments = post.get('comments');

    var activeComments = comments.filter(function(comment) {
      if (comment.get('isActive')) { return true; }
    });

    this.controllerFor('post').set('filteredComments', activeComments);
  }
});


<ul>
    {{#each comment in filteredComments}}
        <li>{{comment.rank}} {{comment.description}} - isActive: {{comment.isActive}}</li>
    {{/each}}
</ul>

您将对这些问题给予的任何见解将不胜感激!

3 个答案:

答案 0 :(得分:39)

  

但是对于一个,我认为sortProperties只适用于arrayControllers,我认为它不能超过一个级别。我怎么能做到这一点?

您是正确的sortProperties仅适用于Ember.ArrayController

你真的不需要做任何想要实现这一点的事情。只需将comments数组包装在一个包含可排序mixin的新ArrayProxy中。然后您可以对评论进行排序。那么你不需要nest属性,因为你正在对一组注释进行排序。

请不要延长DS.ManyArray。没有必要这样做。

至于排序和过滤,您需要在此处使用合成。这意味着要创建filteredContentsortedContent之类的内容。然后,您可以sortedContent使用filteredContent

更新

PostController = Ember.ObjectController.extend({
  comments: (function() {
    return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
      sortProperties: ['rank'],
      content: this.get('content.comments')
    });
  }).property('content.comments')

答案 1 :(得分:2)

这也可以通过计算属性宏来完成。

PostController = Ember.ObjectController.extend({
 commentSortProperties: ['rank:desc', 'createdAt:asc'],
 comments: Em.computed.sort('model.comments', 'commentSortProperties')
});

Take a look at the code here

答案 2 :(得分:0)

也许你可以通过扩展商店并在createManyArray方法中添加可排序的mixin来使你的多数组排序? (我没有测试它是否有效)

App.store = DS.Store.create({
  createManyArray: function (type, clientIds) {
    var array = DS.ManyArray.create(Ember.SortableMixin, { type: type, content: clientIds, store: this });

    clientIds.forEach(function (clientId) {
        var recordArrays = this.recordArraysForClientId(clientId);
        recordArrays.add(array);
    }, this);

    return array;
  }
});

然后你可以绑定到数组的arrangeContent

{#each comment in filteredComments.arrangedContent}}