我有一个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/
答案 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变量。