У меня есть 3 модели: type
, restriction
и item
.
A type
прост и имеет только id
:
app/models/type.js
import Model from 'ember-data/model';
export default Model.extend({});
A restriction
может иметь множество type
, описывающих допустимые типы для элемента с этим ограничением:
app/models/restriction.js
import Model from 'ember-data/model';
import { hasMany } from 'ember-data/relationships';
export default Model.extend({
allowedTypes: hasMany( "type" )
});
An item
может иметь много type
, но также может иметь много restriction
и type
должно быть только подмножеством пересечения разрешенных типов для всех ограничений (и если есть хотя бы одно ограничение, то оно должно иметь хотя бы один тип).
Я реализовал проверку для этого с помощью вычисляемого свойства:
app/models/item.js
import Model from 'ember-data/model';
import { computed } from '@ember/object';
import { hasMany } from 'ember-data/relationships';
import { isEmpty } from '@ember/utils';
const peekHasMany = attr => ( item => item.hasMany( attr ).ids() );
const hasItems = array => !isEmpty( array );
const includedIn = array => ( item => array.indexOf( item ) >= 0 );
const intersectionOf = ( array1, array2, index ) => index >= 0 ? array1.filter( includedIn( array2 ) ) : array2;
export default Model.extend({
types: hasMany( "type" ),
restrictions: hasMany( "restriction" ),
isValidTypes: computed(
"types.[]",
"restrictions.@each.allowedTypes",
function(){
let restrictions = this.hasMany( "restrictions" ).value();
if ( isEmpty( restrictions ) )
{
return true;
}
let allowed = restrictions
.map( peekHasMany( "allowedTypes" ) )
.filter( hasItems );
if ( isEmpty( allowed ) )
{
return true;
}
let types = this.hasMany( "types" ).ids();
if ( isEmpty( types ) )
{
return false;
}
let allowedTypes = allowed.reduce( intersectionOf );
return types.every( includedIn( allowedTypes ) );
}
)
});
При этом используется DS.Model.hasMany( attributeName )
для синхронного получения HasManyReference
для отношений, основанных на загружаемых ссылочных моделях.
Как я могу изменить вычисляемое свойство, чтобы использовать this.get()
для асинхронного получения обоих атрибутов (и дочерних атрибутов) вместо использования this.hasMany()
синхронно?