Как проверить существует ли компонент

Давным-давно (а именно в версии 1.11 от 27 марта 2015 года) в EmberJS был добавлен хэлпер component. Он принимает первым параметром имя компонента, который надо отобразить. Если требуемого компонента нет, то появляется js-ошибка. Можно ли перед отрисовкой как-то проверить существует ли компонент? Да, можно.

В нашем распоряжении есть getOwner (либо из коробки для версии 2.3+, либо из аддона ember-getowner-polyfill для более ранних версий), который возвращает экземпляр приложения, к которому пренадлежит переданный объект. Что же это за объект? Контроллер, компонент, роут, хэлпер и т.д. В свою очередь у экземпляра приложения есть метод hasRegistration (#), который проверяет, зарегистрированна ли сущность, имя которой передано. Пример:

// app/controllers/some-page.js
import Ember from 'ember';
 
const {computed, getOwner} = Ember;
 
export default Ember.Controller.extend({
 
  componentName: computed('modelName', function () {
    const modelName = this.get('model.name');
    return `${modelName}-component`;
  }),
 
  componentExists: computed('componentName', function () {
    const componentName = this.get('componentName');
    const owner = getOwner(this);
    return owner.hasRegistration(`component:${componentName}`) || 
      owner.hasRegistration(`template:components/${componentName}`);
  })
 
});

Пример использования:

{{! app/templates/some-page.hbs }}
{{#if componentExists}}
  {{component componentName data=model}}
{{else}}
  {{default-component data=model}}
{{/if}}

componentExists получилось достаточно универсальным и его можно вынести в отдельный хэлпер:

// app/helpers/component-exists
import Ember from 'ember';
 
export function compute([componentName]) {
  const owner = getOwner(this);
  return owner.hasRegistration(`component:${componentName}`) || 
    owner.hasRegistration(`template:components/${componentName}`);
}
 
export default Ember.Helper.extend({
  compute
});

В шаблонах он используется так:

{{#if (component-exists componentName)}}
  {{component componentName data=model}}
{{else}}
  {{default-component data=model}}
{{/if}}

Почему мы проверяем помимо компонента еще и отдельно шаблон? Возможная ситуация, что компонента как такового нет, а вот шаблон с требуемым именем в папке templates/components есть.

По такому-же принципу работает хэлпер из ember-cli-is-component.

Помимо компонентов можно проверять и доступность разных хэлперов. Пример:

// app/helpers/helper-exists
import Ember from 'ember';
 
const {getOwner} = Ember;
 
export function compute([helperName]) {
  return getOwner(this).hasRegistration(`helper:${helperName}`);
}
 
export default Ember.Helper.extend({
	compute
});

Но это уже более узкопрофильная задача и нужна далеко не всем и не всегда.

Демка с разными случаями доступна по ссылке — ember-twiddle.

, ,

Оставить комментарий

Top ↑ | Main page | Back