Если вы любите Bootstrap, активно используете его в работе и решили с головой окунуться в мир ember.js, то вас ожидает увлекательнейшее путешествие по закоулкам Stack Overflow в поисках ответов на десятки вопросов. Мой путеводитель по галактике по Ember.js способен дать ответ на некоторые из них, например:
Как использовать модальные окна Bootstrap в Ember.js?
Прежде чем перейти к ответу, необходимо эффектное вступление для моего путеводителя в целом. Недолго думая вспомнились два коротких слова, которые непременно поддержат тех, кто хочет покоритьвселенную ember.js
«DON'T PANIC!»
Хорошее, начало. Поехали!
Давайте прикинем, что необходимо учесть при использовании модальных окон:
Модальное окно будем загружать через вспомогательный {{outlet 'modal'}}. К примеру мы хотим сделать редактирование песен на странице /songs. Темплейт для /songs будет выглядеть так:
Теперь нам необходимо создать компонент modal-window.hbs и вынести в него все элементы шапки и футера модального окна.
В нем разместим следующий код:
Обратите внимание, мы добавили переменную {{size}}. В нее будем передавать класс для регулирования размера модального окна (modal-sm, modal-lg). По аналогии можно добавлять классы к любому другому блоку.
{{yield}} — это то место, где будет отображаться основная часть модального окна. К ней вернемся чуть позже. Если вы не знаете, как использовать компоненты, ознакомиться с оф.гайдом можно тут.
Неплохо было бы сразу добавить действия для кнопок «сохранить» и «закрыть», которые расположены в футере модального окна. Для этого добавим в класс нашего компонента components/modal-window.js следующий код:
Теперь самое интересное.
Создадим новый темплейт, который будет отображаться в {{yield}} созданного выше компонента и он же будет загружаться в {{outlet 'modal'}}
Вставим туда следующий код
Мы передали параметры компоненту (title, size, save, close). Теперь создадим контроллер для этого темплейта:
Добавим туда экшен для кнопки «save»:
Заключительный этап — нам нужно указать какой именно темплейт с какими параметрами грузить в {{outlet 'modal'}}.
Для этого достаточно передать параметры через кнопку вызова модального окна:
Затем вешаем обработчик для 'showModal' прямо в route темплейта, в котором находится {{outlet 'modal'}}, в нашем случае это routes/songs:
Еще раз о главном.
По нажатию на кнопку вызова модального окна мы получаем следующие параметры:
Затем вызывается метод showModal, который помещает темплейт модального окна с нужной моделью в {{outlet: 'modal'}}
В темплейте модального окна подгружается компонент модального окна, а в месте с ним и функция show, которая отобразит модальное окно на экране.
Готово! Спасибо за внимание.
P.S.: Спасибо EmberGuru за идею.
Как использовать модальные окна Bootstrap в Ember.js?
Прежде чем перейти к ответу, необходимо эффектное вступление для моего путеводителя в целом. Недолго думая вспомнились два коротких слова, которые непременно поддержат тех, кто хочет покорить
«DON'T PANIC!»
Хорошее, начало. Поехали!
Давайте прикинем, что необходимо учесть при использовании модальных окон:
- простая интеграция в любые части приложения
- передача различных моделей в модальные окна, в зависимости от ситуации
- регулировка размеров и стилей модальных окон
Модальное окно будем загружать через вспомогательный {{outlet 'modal'}}. К примеру мы хотим сделать редактирование песен на странице /songs. Темплейт для /songs будет выглядеть так:
// templates/songs
/*Ваш код*/
{{outlet 'modal'}} // место для отображения модального окна
Теперь нам необходимо создать компонент modal-window.hbs и вынести в него все элементы шапки и футера модального окна.
ember generate component modal-window
В нем разместим следующий код:
/templates/components/modal-window.hbs
<div class="modal fade">
<div class="modal-dialog {{size}}"> // {{size}} - переменная для динамического изменения модального окна
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">{{title}}</h4> //название модели
</div>
<div class="modal-body">
{{yield}} // сюда будем грузить уникальный контент модального окна
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" {{action 'save'}}>Сохранить изменения</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Обратите внимание, мы добавили переменную {{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'}}
<form {{action 'save' on='submit'}}>
{{input type="text" value=name class="form-control"}}
{{input type="text" class="form-control" value=fromServ}}
</form>
{{/modal-window}}
Мы передали параметры компоненту (title, size, save, close). Теперь создадим контроллер для этого темплейта:
ember generate controller modals/song
Добавим туда экшен для кнопки «save»:
// controlers/modals/song
actions: {
save: function() {
// действие
}
}
Заключительный этап — нам нужно указать какой именно темплейт с какими параметрами грузить в {{outlet 'modal'}}.
Для этого достаточно передать параметры через кнопку вызова модального окна:
// templates/songs - темплейт для вывода списка песен
/*Ваш код*/
<button {{
action 'showModal' //этот экшен создадим далее
'modals/song' //передаем нужный темплейт
model //передаем нужную модель
}}>
Редактировать
</button>
{{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'
});
},
}
Еще раз о главном.
По нажатию на кнопку вызова модального окна мы получаем следующие параметры:
- action 'showModal' — который описываем в рауте того темплейта, в котором хотим отобразить модальное окно
- 'modals/song' — темплейт, который будет загружен вместе с компонентом модального окна
- model — модель для данного модального окна
Затем вызывается метод showModal, который помещает темплейт модального окна с нужной моделью в {{outlet: 'modal'}}
В темплейте модального окна подгружается компонент модального окна, а в месте с ним и функция show, которая отобразит модальное окно на экране.
Готово! Спасибо за внимание.
P.S.: Спасибо EmberGuru за идею.
Комментарии (7)
arvitaly
19.11.2015 05:00Кнопку для открытия тоже лучше сделать специальным компонентом, чтобы в каждом маршруте не писать однотипный код.
DSL88
вместо {{size}} лучше использовать classNameBindings компонента для того, чтобы повесить на весь div модального компонента
DSL88
Также вместо this.$('.modal') лучше использовать this.element из-за той же причины
DSL88
да, простите, this.element можно заменить даже на this.$()