Подтвердить что ты не робот

Ember.js сортирует и фильтрует дочерние элементы отношений hasMany в родительском маршруте

Обновление # 2

Я обнаружил, что когда я реорганизовал логику фильтрации в составное вычислительное свойство в PostController, а не в отдельных маршрутах, я смог заставить его работать. Решение в конечном счете зависело от одной динамической переменной, заданной конкретным действием #linkTo route, которое инициировало фильтрацию изменений в вычисляемом свойстве PostController. У меня есть много работы, чтобы догнать, поэтому я не могу опубликовать решение этого конкретного вопроса сейчас, но когда я смогу, я подробно объясню приведенное ниже решение. На данный момент я отметил @twinturbo ответ как правильный для частичного, но невероятно полезного руководства, которое он дал ниже. Еще раз спасибо! Очень признателен!!

Обновление # 1

Последний скрипт находится в http://jsfiddle.net/aZNRu/14/ с помощью справки @twinturbo, сортировка атрибута "rank" комментариев в его родительском контроллере Post работает, наряду с базовой фильтрацией. По-прежнему возникает проблема не получать автоматическое обновление просмотров, когда в отфильтрованном маршруте и создается новый комментарий.

Оригинальный вопрос

Я вижу, что идет речь о объединении сортируемого 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');
     });
   });
});

Я хочу иметь возможность сортировать каждый комментарий в порядке возрастания по атрибуту "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>

Любое понимание, которое вы могли бы дать по этим вопросам, было бы весьма полезно!

4b9b3361

Ответ 1

но для одного, я думаю, sortProperties работает только на arrayControllers, и я не думаю, что он может работать более одного уровня. Как я мог достичь этого?

Вы правы, что sortProperties работает только на Ember.ArrayController.

Вам действительно не нужно ничего делать, чтобы достичь этого. Просто оберните массив комментариев в новый ArrayProxy, который включает сортируемый mixin. Затем вы можете сортировать комментарии. Тогда вам не нужно свойство гнезда, потому что вы сортируете массив комментариев.

Пожалуйста, не расширяйте DS.ManyArray. Это не нужно.

Что касается сортировки и фильтрации, вам нужно использовать композицию здесь. Это означает создание чего-то типа filteredContent и sortedContent. Тогда вы можете использовать sortedContent filteredContent.

Update:

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

Ответ 2

Это также можно сделать с помощью макроса вычисляемого свойства.

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

Взгляните на код здесь.

Ответ 3

Возможно, вы можете сортировать свои многостраничные массивы, расширив хранилище и добавив сортируемый mixin в метод createManyArray? (Я не тестировал, работает ли он)

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}}