Как добиться функциональности сортировки в Ember 2.1.8 для Async = истинные отношения - PullRequest
0 голосов
/ 16 октября 2018

У меня есть следующие вычисленные свойства, шаблон и модель, в которой есть отношения async = true

ArrayController используется для сортировки карточек людей 1-й после обновления до 2.1.8, он не работает.как этого добиться?

вычисленные свойства

 people: computed(
    'model.coordinators',
    'model.directors',
    'model.professors',
    'model.students',
    'model.advisors',
    'model.managers',
    'model.contacts',
    'model.consultants',
    'model.guests',


    function() {

      console.log("people......")

      var coordinators = this.get( 'model.coordinators' ),
          professors   = this.get( 'model.professors' ),
          guests       = this.get( 'model.guests' ),
          students     = this.get( 'model.students' ),
          advisors     = this.get( 'model.advisors' ),
          directors    = this.get( 'model.directors' ),
          consultants  = this.get( 'model.consultants' ),
          contacts     = this.get( 'model.contacts' ),
          managers     = this.get( 'model.managers' ),
          people       = A();

      coordinators.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'coordinators', title:'Coordinator', selected:false } ) );
      } );

      professors.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'professors', title:'Faculty', selected:false } ) );
      } );

      guests.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'guests', title:'Guest', selected:false } ) );
      } );

      students.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'students', title:'Participant', selected:false } ) );
      } );

      advisors.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'advisors', title:'Programme Advisor', selected:false } ) );
      } );

      directors.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'directors', title:'Programme Director', selected:false } ) );
      } );

      consultants.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'consultants', title:'Programme Consultant', selected:false } ) );
      } );

      contacts.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'contacts', title:'Programme Contact', selected:false } ) );
      } );

      managers.forEach( function( person ) {

        people.pushObject( EmberObject.create( { person:person, id:person.id, role:'managers', title:'Programme Management', selected:false } ) );
      } );

    return people;
  } ),
  peopleWithoutDuplicates: computed( 'people' ,function() {

    var dedupedPeople = {},
        people = this.get( 'people' );

    people.forEach( person => dedupedPeople[ person.id ] = person );

    return Object.keys( dedupedPeople ).map( id => dedupedPeople[ id ] );
  } ),

  groupedPeople: computed( 'peopleWithoutDuplicates', 'filter', function() {

    var people    = this.get( 'peopleWithoutDuplicates' ),
        tabPeople = A(),
        getFilter = this.get( 'filter' ),
        arrayController;

    if ( getFilter === 0 || getFilter === 1 ) {

      tabPeople.pushObjects( people.filterBy( 'role', 'coordinators' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'directors' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'professors' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'advisors' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'managers' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'contacts' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'consultants' ) );
      tabPeople.pushObjects( people.filterBy( 'role', 'guests' ) );
    }

    if ( getFilter === 0 || getFilter === 2 ) {

      tabPeople.pushObjects( people.filterBy( 'role', 'students' ) );
    }

    arrayController = Ember.Controller.create( {

   model: tabPeople,
   sortProperties: [ 'person.lastName' ],
   sortAscending: true
    } );

return arrayController
  } ),





  filteredResults: computed( 'filterText', 'groupedPeople.[]', function() {

    var filter = this.get( 'filterText' ).replace( /\s+([^\s]+)/, '|$1').replace( /\s+$/, '' ),

        regExp = new RegExp( filter, 'i' ),
        filteredResults = this.get('groupedPeople').filter(function(result) 
        {
          return regExp.test( result.get( 'person.fullName' ) );
        } );

    return filteredResults;
  } ),

обновлен код с помощью @lux и он все еще не работает

export default Mixin.create( {
  animate: true,
  filterText: '',
  filter: 0,
  filterTabs: A(),
  card: null,
  changeofperson:null,
  people:A(),

  people: computed(
    'model.coordinators.[]',
    'model.directors.[]',
    'model.professors.[]',
    'model.students.[]',
    'model.advisors.[]',
    'model.managers.[]',
    'model.contacts.[]',
    'model.consultants.[]',
    'model.guests.[]',

    function() {
      debugger;
      var people = A();
      this.get( 'model.coordinators.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'coordinators', title:'Coordinator', selected:false } ) );
      } );

      this.get( 'model.professors.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'professors', title:'Faculty', selected:false } ) );
      } );

      this.get( 'model.guests.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'guests', title:'Guest', selected:false } ) );
      } );

      this.get( 'model.students.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'students', title:'Participant', selected:false } ) );
      } );

      this.get( 'model.advisors.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'advisors', title:'Programme Advisor', selected:false } ) );
      } );

      this.get( 'model.directors.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'directors', title:'Programme Director', selected:false } ) );
      } );

      this.get( 'model.consultants.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'consultants', title:'Programme Consultant', selected:false } ) );
      } );

      this.get( 'model.contacts.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'contacts', title:'Programme Contact', selected:false } ) );
      } );

      this.get( 'model.managers.[]' ).forEach( function( person ) {

        people.pushObject( Ember.Object.create( { person:person, id:person.id, role:'managers', title:'Programme Management', selected:false } ) );
      } );

      return people;

    }),


    sortedPeople: computed('people', function() {
      debugger;
      return this.get('people').sortBy('person.lastName')
    }),

    peopleWithoutDuplicates: computed( 'sortedPeople' ,function() {

      var dedupedPeople = {},
      people = this.get( 'people' );

      people.forEach( person => dedupedPeople[ person.id ] = person );

      return Object.keys( dedupedPeople ).map( id => dedupedPeople[ id ] );
    } ),

      groupedPeople: computed( 'peopleWithoutDuplicates', 'filter', function() {

        var people    = this.get( 'peopleWithoutDuplicates' ),
        tabPeople = A(),
        getFilter = this.get( 'filter' ),
        arrayController;

        if ( getFilter === 0 || getFilter === 1 ) {

          tabPeople.pushObjects( people.filterBy( 'role', 'coordinators' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'directors' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'professors' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'advisors' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'managers' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'contacts' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'consultants' ) );
          tabPeople.pushObjects( people.filterBy( 'role', 'guests' ) );
        }

        if ( getFilter === 0 || getFilter === 2 ) {

          tabPeople.pushObjects( people.filterBy( 'role', 'students' ) );
        }

        // arrayController = Ember.Controller.create( {
        //
        //   model: tabPeople,
        //   sortProperties: [ 'person.lastName' ],
        //   sortAscending: true
        // } );

        return tabPeople;
      } ),

      filteredResults: computed( 'filterText', 'groupedPeople.[]', function() {

        var sortedArr =this.get('groupedPeople')
        var filter = this.get( 'filterText' ).replace( /\s+([^\s]+)/, '|$1' ).replace( /\s+$/, '' ),
        regExp = new RegExp( filter, 'i' ),

        filteredResults = sortedArr.filter( function( result ) {
          return regExp.test( result.get( 'person.fullName' ) );
        } );

        return filteredResults;
      } ),

      person: Ember.computed( 'card.person', function() {

        return this.get( 'card.person' );
      } ),


    } ); 

template.hbs

{{#each filteredResults as |result|}}
    <div class="grid--column grid--column-3">

      {{people-card card=result loaded=result.person.isLoaded openProfileAction="openProfile" profileLoadedAction="personLoaded" }}

    </div>
  {{/each}}

модель

{
    coordinators: DS.hasMany( 'profile', { async: true } ),
    directors: DS.hasMany( 'profile', { async: true } ),
    professors: DS.hasMany( 'profile', { async: true } ),
    students: DS.hasMany( 'profile', { async: true } ),
    advisors: DS.hasMany( 'profile', { async: true } ),
}

я пытаюсь показать отсортированный список карточек людей в шаблоне (сортировка по фамилии).это работает под ember 1.13 , но когда я обновился до ember2.1.8 , я получаю сообщение об ошибке ArrayController обесценивается.как добиться сортировки для этих асинхронных = истинных отношений, чтобы работать снова?

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

если вам нужен подробный ответ, я использовал этот ответ для решения своей проблемы

Сортировать массив объектов Ember с обещаниями

0 голосов
/ 18 октября 2018

На самом деле я не очень понимаю, почему ваш текущий код работает.Потому что, если это произойдет, это также будет работать с sortBy.

Проблема, которую вы упоминаете с асинхронными отношениями, верна.Однако AFAIK ваш текущий код не должен работать, потому что ключи зависимости people неверны.

В основном у вас есть два способа решения вашей проблемы:

  1. с помощью обещанийи возвращая PromiseArray
  2. , используя вычисленные свойства

. Существует также ember-computed-promise, который я написал для решения подобных проблем.Это скорее эксперимент.

Так что для использования вычисляемых свойств сначала нужно исправить ключ зависимости вашего вычисляемого свойства people.Тогда это может выглядеть так:

people: computed(
  'model.coordinators.[]',
  'model.directors.[]',
  ...
  function() {
    [
      'coordinators',
      'directors',
      ...
    ].forEach(n => this.get(`model.${n}`).map(person => EmberObject.create({
      person,
      id: person.id,
      selected: false,
    }))).reduce((a, b) => [...a, ...b], []);
  }
),

Я также показал вам, как вы можете сделать это проще.Для role и title вы можете использовать объект поиска.

Теперь этот CP должен всегда содержать всех людей, и когда больше людей загружаются асинхронно, он обновляется.Это важно.Теперь вы можете просто отсортировать их (или сделать что-нибудь с ними):

sortedPeople: computed('people', function() {
  return this.people.sortBy('person.lastName')
})

, это будет работать надежно, потому что всякий раз, когда новые люди добавляются, потому что они загружены, people CP удаляется, а sortedPeople перезапускается.

Если вы хотите использовать ember-computed-promise, это позволит вам использовать асинхронную функцию, которая может сделать ваш код довольно читабельным:

sortedPeople: computedPromise('model', async function() {
  const data = await RSVP.hash({
    coordinators: this.get('model.coordinators'),
    ...
  });

  const people = [];
  data.coordinators.forEach(person => people.push(EmberObject.create({
    person: person,
    id: person.id,
    role: 'coordinators',
    title: 'Coordinator',
    selected: false
  })));

  ...


  return people.sortBy('person.lastName')
})

Здесь вы в основном активны ожидание данных для загрузки.Преимущество этого заключается в том, что будет довольно просто показать загрузочный счетчик (результат будет надежным null), в то время как с другим решением данные будут добавляться по мере поступления.

Я не буду объяснять вподробно, как использовать PromiseArray, потому что я настоятельно рекомендую отойти от Proxy Objects в ember 3.1+, потому что вы не можете использовать для них нативные методы получения.

...