Как лучше всего использовать переменную для всех экземпляров компонента Ember?

У меня есть компонент Ember, который по сути является панелью. На странице может быть несколько экземпляров этой панели, но только один из них может быть «активным» в любой момент времени. Каждый экземпляр компонента должен знать, если какая-либо из других панелей становится «активной», чтобы они могли удалить свое «активное» состояние. Я действительно не хотел бы перемещать JavaScript, чтобы это произошло с родительским компонентом. Вместо этого я хотел бы сохранить его в этом компоненте. В Angular я использовал для этого статическую переменную. Как лучше всего это сделать в Ember?


person soultrust    schedule 20.12.2017    source источник


Ответы (2)


Я действительно предпочел бы не перемещать JavaScript, чтобы это произошло с родительским компонентом.

Вы хотите избежать того, чтобы родительский компонент имел дело с чем-либо, связанным с «активностью» панели? Если да, то почему?* Если нет:

Ember автоматически присваивает тегу каждого компонента (если это не компонент без тегов) идентификатор, который доступен из кода js как elementId. Вы можете создать свойство activePanelId в родительском компоненте и передать его всем панелям: {{pa-nel activePanelId=activePanelId}} а затем проверить в каждой панели

{{#if (eq elementId activePanelId)}}
  {{!whatever is different on the active panel}}
{{/if}}

или используйте его в коде js:

isActive: Ember.computed('activePanelId', function() {
    return this.get('activePanelId')===this.get('elementId');
},

Если панель становится активной в результате действия, связанного с самой собой (например, щелчка по ней), просто установите activePanelId на elementId в соответствующем действии — поскольку свойство activePanelId существует только один раз в родительском компоненте, все другие панели, которым оно передается, будут принять к сведению.

Если использование elementId кажется хакерским, вы можете также дать каждой панели отдельное имя и сохранить activePanelName в вызывающем компоненте.

* Если вам действительно не нужно свойство в родительском компоненте, вы можете переместить его в службу, которую затем внедрите в компоненты панели, но я пока не могу представить веских причин для предпочтения этого.

person arne.b    schedule 20.12.2017
comment
Как насчет использования контекстных компонентов? Документы Ember — guides.emberjs.com/v2.17.0/components/, чтобы вы могли иметь заголовок панели и использовать помощник компонента - person rossjha; 21.12.2017
comment
@rossjha Я никогда ими не пользовался (и мне трудно обдумать их так поздно вечером ;-)). Не стесняйтесь писать ответ на его основе - мне было бы интересно посмотреть, как это сработает. - person arne.b; 21.12.2017

@arne.b anwser резюмирует это довольно хорошо, лучший способ обработки состояния компонента с общими родительскими данными, но если вы серьезно относитесь к тому, чтобы не использовать родительский компонент, есть способ сделать это.

Пример:

import Ember from 'ember';

export default Ember.Component.extend({
   sharedObject: {},
   sharedArray: [],
});

В приведенном выше компоненте вы можете использовать sharedObject или sharedArray для обмена состоянием с несколькими экземплярами компонента. Любые изменения в объекте или массиве будут отражены во всех экземплярах одного и того же компонента.

Пример Ember twiddle.

person Suresh Kumar    schedule 21.12.2017
comment
Это не лучший способ сделать что-то, потому что он мутирует прототип компонента. Один непреднамеренный побочный эффект заключается в том, что изменения в прототипе компонента останутся в интеграционных тестах. Это может привести к тому, что более поздние тесты начнутся с данных, которые вы не планировали, и может привести ко всем видам трудно отслеживаемых сбоев. Лучший подход, если вы не хотите создавать родительский компонент, — создать службу (которая по умолчанию является одноэлементной) и внедрить ее в любые компоненты, состояние которых вы хотите разделить. - person Chris Hayes; 01.11.2018