问题
I have a simple belongsTo
model relationship:
contract.js:
export default DS.Model.extend({
object : DS.belongsTo('object'),
....
})
object.js:
export default DS.Model.extend({
street : DS.attr('string'),
zip : DS.attr('string'),
city : DS.attr('string'),
...
})
In my controller for an entity that holds many contracts
, I'd like to sort by the street name of the associated object
, but somehow this
export default Ember.Controller.extend({
sortOrder: ['object.street'],
sortedObjects: Ember.computed.sort('model.contracts', 'sortOrder')
...
});
doesn't work.
Using a custom comparator function a la
function(a, b){
if (a.street > b.street) {
return 1;
} else if (a.street < b.street) {
return -1;
}
}
I found out that a
and b
are Promises
, but somehow I don't see how to get them sorted via a nested attribute (the object's street)
Edit
To clarify the code a little more:
contracts : Ember.computed.alias('model.contracts'),
street: Ember.computed.alias('realty.street'),
sortOrder: ['realty.street'],
sortedOwnedRealties: Ember.computed.sort('contracts.@each.street', function (a, b) {
console.log(Ember.get(a, 'id'));
console.log(Ember.get(a, 'street'));
//return 1;
})
That function prints undefined
to the console for the street
, but the correct id
.
I've renamed object
to realty
for clarity.
回答1:
They are probably PromiseObject
s, which are both, Ember.Object
and Promise
. There are a few things you do that might be not a good idea:
First object
is a reserved keyword. It's not a good idea to have a model or relationship named object
, even if it might work.
Second your computed property has the wrong dependency key. Actually you would want something like 'modelcontracts.@each.object.street'
instead of 'modelcontracts'
, however this will not work because '@each.a.b'
is not supported. The solution is to create an alias to the street on the contract:
street: Ember.computed.alias('object.street'),
And then you can use this as your dependency key: modelcontracts.@each.street
.
Next in your custom comparator function you access a.street
by dot notation. This will not work and is unreliable for ember objects. Always use .get()
to access the properties:
import Ember form 'ember';
const {get} = Ember;
function(a, b){
if(get(a, 'street') > get(b, 'street')) {...}
}
However also notice that without the computed.alias
I've mentioned above it's not get(a, 'street')
but get(a, 'object.street')
.
The problem why your code is not working is probably that object
is loaded async, and so at the time your CP is evaluated the street is not yet loaded. Adding the correct dependency key will probably fix this.
来源:https://stackoverflow.com/questions/39872225/emberjs-computed-sort-sorting-by-associated-model-property