EmberJS computed.sort - sorting by associated model property

旧城冷巷雨未停 提交于 2019-12-11 01:46:18

问题


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 PromiseObjects, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!