Ember动态导航栏

时间:2014-04-28 21:52:11

标签: ember.js

我有一个Ember应用程序,我试图有一个导航栏,允许我更改不同路线的导航项。

最初,我在应用程序模型上使用延迟加载的navItems属性进行导航。 但是,现在我的第一条路线navItems不再代表需要填充导航栏项的内容。 现在,我正在使用类似于此的渲染助手:

{{render 'nav_menu' navItems}}

从那里,我有一个nav_menu模板:

<a href="#">Jump To Category</a>
<div class="dropdown">
    <ul>
        {{#each}}
            <li>
                <a href="#" class="skip" {{bind-attr gumby-goto=gotoSlug}} gumby-offset="-120">{{name}}</a>
            </li>
        {{/each}}
    </ul>
</div>

视图如下:

class App.NavMenuView extends Ember.View
    tagName: 'li'

    didInsertElement: ->
        Ember.run.later(this, @initializeGumby, 1000)

    initializeGumby: ->
        Gumby.init()

稍后运行实际上是一个黑客攻击,因为视图在视图中的上下文在DOM之前完成呈现(并等待它将跳转到存在的ID)。

所以... 我将如何制作它以便可以更改nav_menu视图的上下文,以便我可以更新路由中的值(然后有一个钩子来激活我的DOM侦听器)?

我创建了一个jsbin来概述我到目前为止的一些内容:http://emberjs.jsbin.com/cefutoge/1/

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,一旦我能够弄明白就感觉非常好。

诀窍是从NavItemsController开始并使其扩展Ember.ArrayController。 从那里,添加一个观察器,检查控制器内容的更改,以重新初始化Gumby,以便滚动正常工作。

App.NavItemsController = Ember.ArrayController.extend({
  contentHasChanged: function () {
    Gumby.init();
  }.observes('content')
});

然后,设置应用程序路由以侦听changeNavItems操作:

App.ApplicationRoute = Ember.Route.extend({
    actions: {
        changeNavItems: function (links) {
            this.controllerFor('navItems').set('content', links);
        }
    }
});

这允许navItems在路由(用于处理初始化或转换数据事件),控制器(用于处理应用程序状态事件)或视图/组件(用于基于用户输入的更改)中进行更改时进行设置)。 此操作将通过控制器和路由冒泡,直到它最终到达ApplicationRoute。

因此,只需在路由,控制器或视图中使用send函数即可。 在这种情况下,IndexRoute将执行:

App.IndexRoute = Ember.Route.extend({
    afterModel: function (model, transition) {
        transition.send('changeNavItems', model.links);
    }
});

首先,讨论afterModel的使用: 由于可以使用setupController代替this.send会更容易,但它不适合此处的用例。 如果navBar深入应用程序或需要当前路径的控制器存在,setupController会有意义。 但是,导航栏与IndexController状态无关,一旦加载模型,就可以构建链接。

从我所知道的中使用transition.send允许在与转换相同的运行循环中触发动作,或者可能在之后的循环中触发(想知道该动作)。 触发操作后,在IndexRoute上找不到匹配操作,因此它会冒泡到ApplicationRoute。 调用changeNavItems,然后将内存中加载的NavItemsController的content设置为links变量。

可在http://jsbin.com/cefutoge/8/edit

找到完整的工作示例