2015-09-16 2 views
6

Ember 2.0 прошел долгий путь в направлении создания всего компонента. В скором времени с помощью маршрутизируемых компонентов контроллеры, вероятно, также будут постепенно отключены.Где хранить переходное состояние пользовательского интерфейса в Ember 2.0

Контекст

Однако, существует постоянная проблема сталкивается при создании интерфейса пользователя, который не имеет удовлетворительную картину так далеко: состояние интерфейса пользователя.

Что я беру?

  • состояние Выбора
  • Текущий фокус
  • Сложенных/разложенное состояние в каком-то древовидного

В принципе, любое государство, которое не является частью фактических данных, но должно быть проследить на поэтапно. Раньше это делалось с помощью Controllers, выступая в качестве прокси-серверов. Этот подход теперь устарел. Новый подход - Components везде, к лучшему. Компонент выполняет бухгалтерию, отслеживает переходное состояние, и вы возвращаете свои действия.

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

Вопрос

Создание компонента списка, с учетом следующих требований:

  • можно выбрать Каждый элемент.
  • Состояние выбора изменяет DOM (некоторые привязки классов).
  • Пользователь может нарисовать прямоугольник в компоненте списка, чтобы выбрать сразу несколько элементов.
  • В идеале, все поведение может быть абстрагировано как mixin.

Вопрос: где находится флаг выбора?

Попытки

1) Все является компонентом.

Я создаю каждый элемент подкомпонента, например {{my-list-item}}. Компонент отслеживает состояние выбора. Проблема: как компонент списка может обновить состояние выбора?

2) Переместить состояние из подкомпонентов.

Поместите его в список компонентов. В пределах отдельного массива состояний рядом с списком элементов. Плюсы: в списке есть все необходимое состояние. Минусы: это кошмар, чтобы сохранить его синхронизированным, когда элементы добавляются или удаляются из списка. И это означает, что подкомпонент не имеет доступа к состоянию. Или, может быть, я могу передать их им в качестве значения?

3) Повторное введение прокси.

Чтобы подумать об этом, есть способ поделиться каким-то состоянием: поместить его в модели.Ну, не на реальных моделях, чтобы не загрязнять их локальным состоянием, а настраивая ArrayProxy, который вернет некоторый ObjectProxy для каждого элемента, чтобы сохранить состояние.

Плюсы: это единственное решение, которое мне удалось полностью реализовать. Минусы: инкапсуляция и декапсуляция предметов - это хлопот. Кроме того, после нескольких уровней прохождения, get и set должны пройти через 4 ou 5 прокси, что, я боюсь, будет проблемой с производительностью.

Кроме того, он не подходит для миксинов. Должен ли я абстрагироваться от смешивания смеси HasSelection и смесителя HasFoldableItems и смесителя Sortable, все они нуждаются в каком-то состоянии.

Назад к чертежной доске

Есть некоторые лучше картины я не нашел?

я нашел следующие важные вопросы, но это не привело меня в никуда:

+1

Торан находится на правильном пути, когда государство становится слишком сложным для отдельных компонентов для управления, вытащить государство из щ и приклейте его на службе. Я написал комментарий об этом здесь: http://www.samselikoff.com/blog/comment-on-data-flow-in-ember-apps/ –

ответ

7

Отличный вопрос - я действительно отправился к одному из членов команды ядра ember, чтобы узнать, и в настоящее время это ответ. Поскольку компонент лучше всего остался без гражданства (по большей части), вы можете использовать службу для сохранения этого состояния, которое не вписывается в модель, сохраненную на сервере.

Вот отличный пример того, что Стеф Пеннер вместе взятый, показывающий, как Вы могли бы сохранить «проект электронной почты» в вашем Ember приложении (это не сохранялись бэкенд)

https://github.com/stefanpenner/ember-state-services

Примера компонент для справки (от проекта GitHub выше)

export default Ember.Component.extend({ 
    tagName: 'form', 
    editEmailService: Ember.inject.service('email-edit'), 
    state: Ember.computed('email', function() { 
    return this.editEmailService.stateFor(this.get('email')); 
    }).readOnly(), 

    actions: { 
    save() { 
     this.get('state').applyChanges(); 
     this.sendAction('on-save', this.get('email')); 
    }, 

    cancel() { 
     this.get('state').discardChanges(); 
     this.sendAction('on-cancel', this.get('email')); 
    } 
    } 
}); 
+0

Чтение информации о государственных услугах прямо сейчас. Этот подход выглядит очень хорошо, в основном компоненты будут совместно использовать состояние, когда они используют одно и то же 'stateName'. Тем не менее, кажется, что stateName должно быть предопределено, а это означает, что все экземпляры одного и того же компонента будут иметь одно и то же состояние. Но я вижу, как можно было бы добавить уровень косвенности (иметь только одну услугу, которая может создавать новые статусы имен на лету). Этот подход лучше, чем все, что у меня было в моем вопросе. Тем не менее, я хотел бы оставить вопрос открытым на некоторое время, чтобы узнать, возникают ли другие. – spectras

+0

Хорошо. Острый модуль имеет очень хорошую концепцию. Это должно действительно идти где-то в учебнике ember.js. Он не полностью соответствовал прецеденту, поскольку он нацелен на долгосрочное состояние пользовательского интерфейса, которое не нуждается в управлении жизненным циклом, но я мог бы основываться на идее: я сделал хранилище состояния объектом, что родительский компонент вводит (через attr) в подкомпоненты. ** Минусы **: больше не синглтон, поэтому, возможно, это немного сломает идею. ** Плюсы **: Я могу связать время жизни компонента и состояния, что имеет смысл здесь. – spectras

+0

@spectras. Если бы вы могли предоставить отдельный ответ своим решением? – Jon

Смежные вопросы