Как сделать так, чтобы действие влияло на родственное представление без controller.get('view')?

Краткий контекст: Представление приложения имеет 2 выхода. Один для панели инструментов. Другой для маршрутизируемой «основной» иерархии представлений.

app -- main
   \-- toolbar

Мне нужны некоторые кнопки на панели инструментов для запуска событий в «основном» представлении. Не обновлять данные в любой модели. Я просто даю ему указание инициировать некоторые изменения в библиотеке чертежей, которую представляет вид. Очистка холста, сброс значения масштабирования и тому подобное.

В 1.0 pre2 и более ранних версиях я использовал действия и router.get('someController.view'), чтобы получить доступ к нужному мне представлению и запустить действие/метод/событие. Вряд ли вершина дизайна приложения, но он работал нормально.

Этой опции больше нет, и я не могу найти хорошую альтернативу. Какой механизм следует использовать для связи между представлениями, которые не находятся в дочерней/родительской иерархии? Все, что я придумал, неуклюже и вызывает у меня ощущение, что "У Ember есть способ получше"< /эм>.

Короче хочу:

  • Кнопка на панели инструментов для запуска события
  • Основное представление реагирует на это и выполняет некоторые обновления своих частей.
  • Основное представление НЕ перерисовывать в Ember смысле этого слова, как через маршрутизацию. Он использует библиотеку для рисования, и интеграция всех его свойств и поведения в модели и контроллеры Ember не доставит большого удовольствия.
  • Панель инструментов и основной вид имеют общий родительский вид, но находятся в разных «ветвях».

Плохие варианты, которые я рассматриваю:

Панель инструментов в значительной степени относится к уровню приложения, но на ней есть несколько кнопок, которые должны указывать определенные представления. Один из вариантов, который я вижу в Ember, — это вложить панель инструментов в «основной» вид. Это кажется неправильным для некоторых других функций.

Коммуникация может быть обработана контроллером (и, возможно, даже моделью), который будет содержать свойства, которые устанавливает панель инструментов, а представление «прослушивания» реагирует на и сбрасывает значение. Это звучит как злоупотребление целями контроллера и модели и как довольно плохая настройка прослушивателя событий.

Я мог бы сделать библиотеку рисования глобальным приложением как App.Drawing или что-то в этом роде, но это тоже кажется плохим. Это также будет означать, что действия по-прежнему не смогут использовать какие-либо данные в виде для обновления библиотеки чертежей.

Какие-либо предложения?


person Martin Westin    schedule 30.01.2013    source источник


Ответы (1)


Какой механизм я должен использовать при общении между представлениями, которые не находятся в дочерней/родительской иерархии?

В типичном приложении Ember такое взаимодействие должно происходить между контроллерами. В противном случае «Плохой вариант 2» находится на правильном пути:

Коммуникация может быть обработана контроллером (и, возможно, даже моделью), который будет содержать свойства, которые устанавливает панель инструментов, а представление «прослушивания» реагирует на и сбрасывает значение.

Рассмотрите возможность использования двух контроллеров. Действия панели инструментов будут нацелены на ToolbarController, который отвечает за поддержание состояния панели инструментов и за изменение основного в ответ на действия пользователя. ToolbarController следует объявить зависимость от MainController через свойство needs. Например:

App.ToolbarController = Ember.Controller.extend({
  needs: ['main'],
  buttonOneGotAllPressed: function() {
    main = this.get('controllers.main');
    main.turnOffAnOption();
    main.makeSomeOtherChange();
  }
}); 

Теперь MainController можно сфокусироваться на состоянии MainView. Он не должен знать о ToolbarController или его кнопках.

Это звучит как злоупотребление целями контроллера и модели и как довольно плохая настройка прослушивателя событий.

Согласен, это, вероятно, было бы злоупотреблением целями модели, но именно для этого и нужны контроллеры.

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

Если компоненты действительно разделены, то шаблон наблюдателя (Pub/Sub) может быть более подходящим. См. Как запустить событие в Ember. из другого фреймворка, если это интересно.

person Mike Grassotti    schedule 30.01.2013
comment
Это серьезная магия. Я не мог найти ссылку на использование свойства «нужды» в документации. Ember полон скрытых сюрпризов, я не уверен, что это хорошо. Чрезвычайно сложно получить ментальную модель всей структуры. Больше всего расстраивает то, что нет четкого определения обязанностей классов. - person Denzo; 31.01.2013
comment
Согласитесь, это очень интересная функция. Я бы сразу же пошел по этому пути, если бы менял какое-то состояние в главном представлении. Естественно, это может регулироваться свойством контроллера. Но когда вещь, которую я хочу вызвать в представлении, больше похожа на мигание, отскок и тому подобное, я чувствую себя менее комфортно, связывая это со свойством. НАПРИМЕР. Это будет свойство с именем is_bouncing, которое контроллер изменит на true, а представление сбрасывается на false сразу после того, как увидит, что оно истинно. По сути, это будут логические значения, действующие как триггеры, а не представляющие какое-либо состояние. - person Martin Westin; 31.01.2013
comment
Добавление примечания для дальнейшего использования: теперь это задокументировано на emberjs.com/guides/controllers. /зависимости-между-контроллерами - person Jordan Sitkin; 30.06.2013