Ember mixins - это хороший способ добиться "динамического" макета
Чего я пытаюсь добиться:
В приложении есть несколько "основных разделов", таких как верхняя панель, боковая панель и, конечно, контент. Я хотел бы иметь для каждого маршрута "конфигурацию", которая из них отображается (контент всегда присутствует), с большинством маршрутов, имеющих одинаковое расположение по умолчанию.
Мое решение:
- Шаблон приложения связывает видимость каждого раздела с соответствующим свойством ApplicationController
- У меня есть LayoutMixin, который при входе в маршрут получает свойство layoutSettings маршрута и соответствующим образом обновляет свойства ApplicationController
- При выходе из маршрута, mixin возвращается к предыдущему состоянию
Минималистичный пример: http://emberjs.jsbin.com/fidoquhira/2/edit?html,css,js,output
Этот подход работает, и мне очень нравится концепция использования mixin + "данные конфигурации" для автоматического выполнения задач (я также делаю то же самое для хлебных крошек), но я немного обеспокоен тем, что уменьшаю ясность в том, что или что я не вижу чего-то, что может взорваться в какой-то более поздний момент.
Это "угасающий способ" делать вещи?
Дополнительно: как написать модульные тесты для такого миксина?
1 ответ
Поскольку ваша проблема главным образом связана с тем, какая информация отображается в любой заданной точке, а не с бизнес-логикой, мое решение состояло бы в том, чтобы связать видимость вашей верхней панели и боковой панели со свойствами в контроллере приложения. Если бы вы использовали миксин, я бы использовал тот, который присваивает псевдоним свойствам маршрута приложения и, возможно, дает вам некоторые действия для отображения, скрытия или переключения состояния. Например:
//application controller
export default Ember.Controller.extend({
isTopPanelVisible: false,
isSideBarVisible: false
});
//panel visibility mixin
export default Ember.Mixin.create({
needs: ["application"],
isTopPanelVisible: Ember.computed.alias("controllers.application.isTopPanelVisible"),
isSideBarVisible: Ember.computed.alias("controllers.application.isSideBarVisible"),
actions: {
showTopPanel: function(){
this.set("isTopPanelVisible", true);
},
showSideBar: function(){
this.set("isSideBarVisible", true);
}
}
});
//controller for some route
export default Ember.ObjectController.extend(panelVisibility, {
initializeRoutesVisibility: function(){
this.set("isTopPanelVisible", true);
this.set("isSideBarVisible", false);
}.on("init")
});
//sidebar view
export default Ember.View.extend({
classNameBindings: ["hidden"],
hidden: true,
setVisibility: function(){
if (this.get("controller.isSideBarVisible"){
this.set("hidden", false);
} else {
this.set("hidden", true);
}
}.observes("controller.isSideBarVisible").on("didInsertElement")
});
//top panel view
export default Ember.View.extend({
classNameBindings: ["hidden"],
hidden: true,
setVisibility: function(){
if (this.get("controller.isTopPanelVisible"){
this.set("hidden", false);
} else {
this.set("hidden", true);
}
}.observes("controller.isTopPanelVisible").on("didInsertElement")
});
//some css file
.hidden {
display: none;
}
Я думаю, что это решение более "Ember" и дает вам гораздо больше гибкости. Состояние хранится в одном месте, что все остальное наблюдает, бизнес-логика идет в контроллерах, логика отображения идет в представлениях.