我在我的Ember.js应用中使用Twitter Bootstrap进行导航。 Bootstrap在包含导航链接的active
标记上使用li
类,而不是在链接本身上设置active
类。
Ember.js的新linkTo
助手会在链接上设置一个active
类,但是(据我所知)并没有提供任何可以挂钩的属性。
现在,我正在使用这种丑陋的方法:
{{#linkTo "inbox" tagName="li"}}
<a {{bindAttr href="view.href"}}>Inbox</a>
{{/linkTo}}
这将输出:
<li class="active" href="/inbox"><a href="/inbox">Inbox</a></li>
这就是我想要的,但不是有效的HTML。
我还尝试从父视图绑定到生成的LinkView的active
属性,但如果这样做,父视图将在插入之前呈现两次,从而触发错误。
除了手动重新创建linkTo
帮助器内部使用的逻辑以将active
类分配给链接之外,还有更好的方法来实现这种效果吗?
答案 0 :(得分:27)
我们肯定需要一个更公开,永久的解决方案,但这样的事情现在应该有效。
模板:
<ul>
{{#view App.NavView}}
{{#linkTo "about"}}About{{/linkTo}}
{{/view}}
{{#view App.NavView}}
{{#linkTo "contacts"}}Contacts{{/linkTo}}
{{/view}}
</ul>
视图定义:
App.NavView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['active'],
active: function() {
return this.get('childViews.firstObject.active');
}.property()
});
这取决于几个限制因素:
<li>
的视图。有关如何从JavaScript定义或Handlebars自定义视图元素的详细信息in the docs。我提供了a live JSBin这项工作。
答案 1 :(得分:9)
我接受了@alexspeller的好主意并将其转换为ember-cli:
应用/组件/链路li.js
export default Em.Component.extend({
tagName: 'li',
classNameBindings: ['active'],
active: function() {
return this.get('childViews').anyBy('active');
}.property('childViews.@each.active')
});
在我的导航栏中,我有:
{{#link-li}}
{{#link-to "squares.index"}}Squares{{/link-to}}
{{/link-li}}
{{#link-li}}
{{#link-to "games.index"}}Games{{/link-to}}
{{/link-li}}
{{#link-li}}
{{#link-to "about"}}About{{/link-to}}
{{/link-li}}
答案 2 :(得分:8)
您还可以使用嵌套链接:
{{#link-to "ccprPracticeSession.info" controller.controllers.ccprPatient.content content tagName='li' href=false eventName='dummy'}}
{{#link-to "ccprPracticeSession.info" controller.controllers.ccprPatient.content content}}Info{{/link-to}}
{{/link-to}}
答案 3 :(得分:6)
以katz的答案为基础,您可以在点击导航元素的active
时重新计算parentView
属性。
App.NavView = Em.View.extend({
tagName: 'li',
classNameBindings: 'active'.w(),
didInsertElement: function () {
this._super();
var _this = this;
this.get('parentView').on('click', function () {
_this.notifyPropertyChange('active');
});
},
active: function () {
return this.get('childViews.firstObject.active');
}.property()
});
答案 4 :(得分:5)
我刚刚编写了一个组件,以使其更好一些:
App.LinkLiComponent = Em.Component.extend({
tagName: 'li',
classNameBindings: ['active'],
active: function() {
return this.get('childViews').anyBy('active');
}.property('childViews.@each.active')
});
Em.Handlebars.helper('link-li', App.LinkLiComponent);
用法:
{{#link-li}}
{{#link-to "someRoute"}}Click Me{{/link-to}}
{{/link-li}}
答案 5 :(得分:2)
我重新创建了内部使用的逻辑。其他方法似乎更加骇人。这也可以更容易地重用我可能不需要路由的其他地方的逻辑。
像这样使用。
{{#view App.LinkView route="app.route" content="item"}}{{item.name}}{{/view}}
App.LinkView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['active'],
active: Ember.computed(function() {
var router = this.get('router'),
route = this.get('route'),
model = this.get('content');
params = [route];
if(model){
params.push(model);
}
return router.isActive.apply(router, params);
}).property('router.url'),
router: Ember.computed(function() {
return this.get('controller').container.lookup('router:main');
}),
click: function(){
var router = this.get('router'),
route = this.get('route'),
model = this.get('content');
params = [route];
if(model){
params.push(model);
}
router.transitionTo.apply(router,params);
}
});
答案 6 :(得分:1)
您可以跳过扩展视图并使用以下内容。
{{#linkTo "index" tagName="li"}}<a>Homes</a>{{/linkTo}}
即使没有href,Ember.JS仍然会知道如何挂钩LI元素。
答案 7 :(得分:0)
对于同样的问题,我来自基于jQuery的解决方案,不确定性能损失,但它开箱即用。我重新打开Ember.LinkView并扩展它。
Ember.LinkView.reopen({
didInsertElement: function(){
var el = this.$();
if(el.hasClass('active')){
el.parent().addClass('active');
}
el.click(function(e){
el.parent().addClass('active').siblings().removeClass('active');
});
}
});
答案 8 :(得分:0)
撰写本文时的答案已过时。在Ember的更高版本中,如果您使用{{link-to}}
,当当前路由与目标链接匹配时,它会在'active'
元素上自动设置<a>
类。
因此,只需编写您的css,期望<a>
将active
,并且它应该开箱即用。
幸运的是,该功能已添加。这里所有的东西都需要解决这个问题&#34;问题&#34;先前非常荒谬。