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" и дает вам гораздо больше гибкости. Состояние хранится в одном месте, что все остальное наблюдает, бизнес-логика идет в контроллерах, логика отображения идет в представлениях.

Другие вопросы по тегам