如何在 Ember 2.1.8 中实现 Async=true 关系的排序功能
How to achieve sort functionality in Ember 2.1.8 for Async=true relationships
我有以下计算属性、模板和模型,其中存在 async=true 的关系
ArrayController 用于在升级到 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]+)/, '|').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]+)/, '|' ).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 is depreciated。
如何实现那些 async=true 关系的排序以再次工作?
其实我不太明白为什么你现在的代码可以工作。因为如果这样做,它也可以与 sortBy
.
一起使用
你提到的异步关系问题是真实的。但是 AFAIK 您当前的代码应该不能正常工作,因为 people
的依赖键是错误的。
基本上你有两种方法可以解决你的问题:
- 通过使用 promise 并返回一个 PromiseArray
- 利用计算属性
我还写了 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
,因为我强烈建议在 ember 3.1+ 中远离代理对象,因为您不能为它们使用本地 getter。
如果你需要一个详细的答案,我用这个答案来解决我的问题
我有以下计算属性、模板和模型,其中存在 async=true 的关系
ArrayController 用于在升级到 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]+)/, '|').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]+)/, '|' ).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 is depreciated。 如何实现那些 async=true 关系的排序以再次工作?
其实我不太明白为什么你现在的代码可以工作。因为如果这样做,它也可以与 sortBy
.
你提到的异步关系问题是真实的。但是 AFAIK 您当前的代码应该不能正常工作,因为 people
的依赖键是错误的。
基本上你有两种方法可以解决你的问题:
- 通过使用 promise 并返回一个 PromiseArray
- 利用计算属性
我还写了 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
,因为我强烈建议在 ember 3.1+ 中远离代理对象,因为您不能为它们使用本地 getter。
如果你需要一个详细的答案,我用这个答案来解决我的问题