22

更新#2

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

更新#1

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

原始问题

我看到有人谈论将可排序的 mixin 与过滤功能相结合,但是现在,正如您在我的jsfiddle 示例中看到的那样,我在排序和过滤方面都遇到了问题:

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');
     });
   });
});

我希望能够通过它的“排名”属性按升序对每个帖子的评论进行排序。我想做类似的事情:

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

但一方面,我认为 sortProperties 仅适用于 arrayControllers,而且我认为它的工作深度不能超过一层。我怎么能做到这一点?

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

我是在路由中错误地设置路由过滤还是在模板中引用错误?

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>

您可以就这些问题提供任何见解,我们将不胜感激!

4

3 回答 3

39

但一方面,我认为 sortProperties 仅适用于 arrayControllers,而且我认为它的工作深度不能超过一层。我怎么能做到这一点?

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

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

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

至于排序和过滤,这里需要用到合成。这意味着创建类似filteredContentand的东西sortedContent。然后就可以sortedContent使用了filteredContent

更新:

PostController = Ember.ObjectController.extend({
  comments: (function() {
    return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
      sortProperties: ['rank'],
      content: this.get('content.comments')
    });
  }).property('content.comments')
于 2013-02-11T21:40:38.253 回答
2

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

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

看看这里的代码

于 2014-10-30T21:28:31.987 回答
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;
  }
});

然后您可以绑定到数组的排列内容

{#each comment in filteredComments.arrangedContent}}
于 2013-01-30T11:49:06.520 回答