Ember mixins - 这是实现'动态'布局的好方法

时间:2014-11-05 14:44:15

标签: javascript ember.js architecture mixins

我想要实现的目标:

该应用有几个"主要部分",例如顶部面板,侧边栏,当然还有内容。我想有一个按路由配置'其中显示了哪些(内容始终存在),大多数路线具有相同的默认布局。

我的解决方案:

  • 应用程序模板将每个部分的可见性绑定到相关的ApplicationController属性
  • 我有一个LayoutMixin,在进入路径后,获取路由的layoutSettings属性,并相应地更新ApplicationController属性
  • 离开路线时,mixin会恢复之前的状态

简约示例:http://emberjs.jsbin.com/fidoquhira/2/edit?html,css,js,output

该方法有效,我非常喜欢使用mixin +'配置数据'让事情自动发生' (我也为面包屑做了类似的事情),但我有点担心我会减少正在发生的事情的清晰度,或者我没有看到可能会在以后发生的事情

这是" Ember方式"做事?

另外:如何为这样的mixin编写单元测试?

1 个答案:

答案 0 :(得分:0)

由于您的问题主要处理在任何给定点而不是业务逻辑上显示的信息,因此我的解决方案是将顶部面板和侧边栏视图的可见性绑定到应用程序控制器中的属性。如果你要使用mixin,我会使用一个在应用程序路由中使用别名属性的方法,并且可能会给你一些显示,隐藏或切换状态的操作。例如:

//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”,为您提供了更多的灵活性。状态存储在一个地方,其他一切都在观察,业务逻辑在控制器中,显示逻辑在视图中。