什么是导航侧边栏的“正确方式”(或者至少是选项,如果没有单一的“Ember方式”来完成这个)?我应该以某种方式查看ContainerViews,还是应该只使用新的outlet功能并将导航置于我的应用视图内?
此外,根据URL(我正在使用路由),设置li上的.active类的“正确方法”是什么?是否有一些辅助函数可以实现这个?
什么是导航侧边栏的“正确方式”(或者至少是选项,如果没有单一的“Ember方式”来完成这个)?我应该以某种方式查看ContainerViews,还是应该只使用新的outlet功能并将导航置于我的应用视图内?
此外,根据URL(我正在使用路由),设置li上的.active类的“正确方法”是什么?是否有一些辅助函数可以实现这个?
<更新日期="2013-01-16">
由于路由器API的最新更改,之前的示例已不再有效,因此我不会修复它们。所有使用旧路由器的应用程序都应尽快迁移到最新版本。
我将定期维护/修复/添加功能。
编辑于2013年4月3日:
<更新>
2012年11月9日
只需添加一个链接到一个更好的示例,该示例还解决了OP希望在选择给定路由时设置当前导航栏项类的部分
如果您查看NavigationController,您将看到“selected”属性,我在其中使用它来在子视图NavigationItemView的isActive方法中检查。 isActive将根据相同视图中menu
属性的值和控制器中selected
属性的值返回true或false。然后检查classNameBinding表达式,这些表达式将 'active'或无设置为该特定子项的类。
还要检查ConnectOutlets,这是我标记nav项为选定项的位置。
此操作正在最新的Ember上运行。 我还使用了一些Ember.Bootstrap以及一些原始Twitter Bootstrap功能/类等(但我已将样式替换为metro-bootstrap)。
不会在此处粘贴整个内容,因为空间有限。我将保留原始代码和链接以供参考。
我会继续更新这个新示例,因为Ember很有趣=)
</Update>
这个 fiddle 显示了一个静态导航栏的视图,outlet 仅用于内容显示,或者你可以直接到显示页面 查看其运行
如你所见,你可以使用简单的视图包含你的动作链接,并在应用程序主视图中呈现此视图。 "starting" 下的子路由也有一个迷你导航栏,来自类似的模板。
Handlebars:
<script type="text/x-handlebars" data-template-name="application"></script>
<script type="text/x-handlebars" data-template-name="navbar"></script>
<script type="text/x-handlebars" data-template-name="getting-started-menu"></script>
<script type="text/x-handlebars" data-template-name="home"></script>
<script type="text/x-handlebars" data-template-name="starting"></script>
<script type="text/x-handlebars" data-template-name="about-mvc"></script>
<script type="text/x-handlebars" data-template-name="about-ember"></script>
<script type="text/x-handlebars" data-template-name="community"></script>
JavaScript:
App = Em.Application.create();
App.ApplicationController = Em.Controller.extend();
App.ApplicationView = Em.View.extend({
templateName: 'application'
});
App.HomeController = Em.Controller.extend();
App.HomeView = Em.View.extend({
templateName: 'home'
});
App.NavbarController = Em.Controller.extend();
App.NavbarView = Em.View.extend({
templateName: 'navbar'
});
App.StartingController = Em.Controller.extend();
App.StartingView = Em.View.extend({
templateName: 'starting'
});
App.StartingMenuController = Em.Controller.extend();
App.StartingMenuView = Em.View.extend({
templateName: 'getting-started-menu'
});
App.AboutMVCController = Em.Controller.extend();
App.AboutMVCView = Em.View.extend({
templateName: 'about-mvc'
});
App.AboutEmberController = Em.Controller.extend();
App.AboutEmberView = Em.View.extend({
templateName: 'about-ember'
});
App.CommunityModel = Em.Object.extend({
displayName: null,
linkUrl: null,
imageUrl: null
});
App.CommunityController = Em.ArrayController.extend({
content: [],
init: function() {
this._super();
this.pushObject(
App.CommunityModel.create({
displayName: 'Twitter',
linkUrl: 'https://twitter.com/#!/emberjs',
imageUrl: 'http://icons.iconarchive.com/icons/iconshots/social-media-network/32/twitter-icon.png'
}));
this.pushObject(
App.CommunityModel.create({
displayName: 'GitHub',
linkUrl: 'https://github.com/emberjs/ember.js',
imageUrl: 'http://www.workinprogress.ca/wp-content/uploads/github.png'
}));
}
});
App.CommunityView = Em.View.extend({
templateName: 'community',
contentBinding: 'App.CommunityController.content'
});
App.Router = Em.Router.extend({
enableLogging: true,
location: 'hash',
root: Em.Route.extend({
// EVENTS
gotoHome: Ember.Route.transitionTo('home'),
gotoStarting: Ember.Route.transitionTo('starting.index'),
gotoCommunity: Ember.Route.transitionTo('community.index'),
// STATES
home: Em.Route.extend({
route: '/',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('home');
}
}),
starting: Em.Route.extend({
// SETUP
route: '/starting',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('starting');
},
// EVENTS
gotoMVC: Ember.Route.transitionTo('mvc'),
gotoEmber: Ember.Route.transitionTo('ember'),
gotoIndex: Ember.Route.transitionTo('index'),
// STATES
index: Em.Route.extend({
route: '/',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('starting');
}
}),
mvc: Em.Route.extend({
route: '/mvc',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('aboutMVC');
}
}),
ember: Em.Route.extend({
route: '/ember',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('aboutEmber');
}
})
}),
community: Em.Route.extend({
// SETUP
route: '/community',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('community');
},
// EVENTS
// STATES
index: Em.Route.extend({
route: '/',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet('community');
}
})
})
})
});
App.initialize();
我不喜欢MilkyWayJoe的回答,因为如果你早晚想要更改你的状态或其他内容的命名,你必须同时修改代码和视图,而且为每个路由添加一个transitionTo函数似乎并不理想。 我的方法更加程序化和模块化:
# Parent View-Tamplate, holding the navbar DOM elements
App.NavView = Ember.View.extend(
controller: App.NavArrayController
templateName: "ember-nav"
)
# We push NavItems into this array
App.NavArrayController = Ember.ArrayController.create(
content: Ember.A([])
)
# NavItem has two settable properties and
# an programmatic active state depending on the router
App.NavItem = Ember.Object.extend(
title: ''
goto: null # <=this is the name of the state we want to go to!
active: (->
if App.router.currentState.name == @.get "goto"
true
else
false
).property('App.router.currentState.name').cacheable()
)
# the actual NavElement which gets the class="active" if the
# property "active" is true, plus a on-click binding to
# make the Router transition to this state
App.NavItemView = Ember.View.extend(
tagName: "li"
classNameBindings: ["active"]
click: ->
App.router.transitionTo(@get('goto'))
false
)
<div class="nav-collapse collapse">
<ul class="nav">
{{#each App.NavArrayController}}
{{#view App.NavItemView classBinding="active" gotoBinding="goto"}}
<a href="#" {{bindAttr data-goto="goto"}}> {{title}}</a>
{{/view}}
{{/each}}
</ul>
</div>
# put this somewhere close to the Router
App.NavArrayController.pushObjects(
[
App.NavItem.create(
title: 'Home'
goto: 'home'
),
App.NavItem.create(
title: 'Chat'
goto: 'chat'
),
App.NavItem.create(
title: 'Test'
goto: 'test'
)
]
)
a href="#"
设置为href="/#/{{unbound goto}}"
时才会生效。 - Thomas