[Из песочницы] Путеводитель по Bootstrap + Ember.js. Часть 1: Модальные окна в Эмбере или как подружить Bootstrap Modal и Ember.js

Если вы любите Bootstrap, активно используете его в работе и решили с головой окунуться в мир ember.js, то вас ожидает увлекательнейшее путешествие по закоулкам Stack Overflow в поисках ответов на десятки вопросов. Мой путеводитель по галактике по Ember.js способен дать ответ на некоторые из них, например:

Как использовать модальные окна Bootstrap в Ember.js?

Прежде чем перейти к ответу, необходимо эффектное вступление для моего путеводителя в целом. Недолго думая вспомнились два коротких слова, которые непременно поддержат тех, кто хочет покорить вселенную ember.js

«DON’T PANIC!»

Хорошее, начало. Поехали!
Давайте прикинем, что необходимо учесть при использовании модальных окон:

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


Модальное окно будем загружать через вспомогательный {{outlet 'modal'}}. К примеру мы хотим сделать редактирование песен на странице /songs. Темплейт для /songs будет выглядеть так:

// templates/songs
/*Ваш код*/

{{outlet 'modal'}} // место для отображения модального окна


Теперь нам необходимо создать компонент modal-window.hbs и вынести в него все элементы шапки и футера модального окна.

ember generate component modal-window


В нем разместим следующий код:

/templates/components/modal-window.hbs



Обратите внимание, мы добавили переменную {{size}}. В нее будем передавать класс для регулирования размера модального окна (modal-sm, modal-lg). По аналогии можно добавлять классы к любому другому блоку.

{{yield}} — это то место, где будет отображаться основная часть модального окна. К ней вернемся чуть позже. Если вы не знаете, как использовать компоненты, ознакомиться с оф.гайдом можно тут.

Неплохо было бы сразу добавить действия для кнопок «сохранить» и «закрыть», которые расположены в футере модального окна. Для этого добавим в класс нашего компонента components/modal-window.js следующий код:

//components/modal-window.js
  actions: {
    save: function() {                                        
      this.$('.modal').modal('hide');                   
      this.sendAction('save');                          
    }
  },
  show: function() {
    this.$('.modal').modal().on('hidden.bs.modal', function() {
      this.sendAction('close');
    }.bind(this));
  }.on('didInsertElement')                                //вызываем функцию после загрузки компонента


Теперь самое интересное.

Создадим новый темплейт, который будет отображаться в {{yield}} созданного выше компонента и он же будет загружаться в {{outlet 'modal'}}

ember generate template modals/song


Вставим туда следующий код

//templates/modals/song.hbs
{{#modal-window title="Добавить песню" size="modal-sm" save='save' close='removeModal'}}
                    
{{input type="text" value=name class="form-control"}} {{input type="text" class="form-control" value=fromServ}}
{{/modal-window}}


Мы передали параметры компоненту (title, size, save, close). Теперь создадим контроллер для этого темплейта:

ember generate controller modals/song


Добавим туда экшен для кнопки «save»:

// controlers/modals/song

  actions: {
    save: function() {
      // действие
    }
  }


Заключительный этап — нам нужно указать какой именно темплейт с какими параметрами грузить в {{outlet 'modal'}}.

Для этого достаточно передать параметры через кнопку вызова модального окна:

// templates/songs - темплейт для вывода списка песен

/*Ваш код*/



{{outlet 'modal'}} // место для отображения модального окна


Затем вешаем обработчик для 'showModal' прямо в route темплейта, в котором находится {{outlet 'modal'}}, в нашем случае это routes/songs:

//routes/songs
        actions: {
           showModal: function(name, model) {
              this.render(name, {
                into: 'songs',
                outlet: 'modal',
                model: model
              });
            },
            removeModal: function() {
              this.disconnectOutlet({
                outlet: 'modal',
                parentView: 'songs'
              });
            },
        }


Еще раз о главном.

По нажатию на кнопку вызова модального окна мы получаем следующие параметры:

  1. action 'showModal' — который описываем в рауте того темплейта, в котором хотим отобразить модальное окно
  2. 'modals/song' — темплейт, который будет загружен вместе с компонентом модального окна
  3. model — модель для данного модального окна


Затем вызывается метод showModal, который помещает темплейт модального окна с нужной моделью в {{outlet: 'modal'}}
В темплейте модального окна подгружается компонент модального окна, а в месте с ним и функция show, которая отобразит модальное окно на экране.

Готово! Спасибо за внимание.

P.S.: Спасибо EmberGuru за идею.

© Habrahabr.ru