2013-01-14 278 views
22

我在我的Ember.js應用程序中使用Twitter Bootstrap進行導航。 Bootstrap在包含導航鏈接的li標記上使用active類,而不是在鏈接本身上設置active類。如何使用新的Ember路由器綁定到鏈接的活動類?

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

由於最近的更改,這甚至不再工作(因爲linkTo幫助程序不再將視圖上下文設置爲其視圖)。 – Bastes

+2

對於任何遇到此問題的人,我發現這些答案更有幫助:http://stackoverflow.com/questions/11628489/emberjs-how-to-mark-active-menu-item-using-router-infrastructure – woz

+1

找到一個更好的解決方案[這裏](http://stackoverflow.com/questions/14412073/assigning-active-class-to-selected-list-item-in-emberjs)。 – Volox

回答

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}} 
+1

請注意,如果tagName!=='a'([source](https://github.com/emberjs/ember.js/pull/1849)) –

+0

,則sine ember v1.0.0-rc.3 href默認爲false我已經改變了接受的答案,因爲這是我現在怎麼做的,並更新了答案,以刪除href = false –

+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() 
}); 

這依賴於幾個限制:

  • 的導航視圖包含一個單一的,靜態的子視圖
  • 您可以使用您的的視圖s。關於如何從JavaScript定義或Handlebars定製視圖的元素,有很多細節in the docs

我提供了a live JSBin這項工作。

+0

是否有任何理由,這不會與一個CollectionView的itemViewClass?它在我看來像itemViewClass的實例沒有任何childViews。 – mcginniwa

+1

@YhhudaKatz很好的解決方案,我剛剛在回答相關問題後發現了這個問題。想象一下,我會在這裏添加評論,因爲我的方法可以幫助任何人被你提到的其中一個約束所困住。完全同意需要更多公共/永久性的東西,會給出一些想法。 http://stackoverflow.com/questions/14412073/assigning-active-class-to-selected-list-item-in-emberjs/14416595#14416595 –

+5

這似乎並不工作(不再?) - 它觸發了一個「您嘗試在呈現視圖之後但在插入到DOM之前重新呈現視圖「錯誤。我的黑客解決方案仍然有效。 –

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); 
    } 
}); 
+2

我接受了這個,因爲它可能是最好的方式去解決它 - 其他答案都與新的Ember.js更新打破。然而,在我的例子中,最簡單也是最可靠的做法是修補bootstrap,以使'a'標籤上的活動類與'li'上的活動類具有相同的效果。 –

+1

可通過在'bootstrap.css'(版本2.3.2)中添加以下行'4634'完成以下操作:'.navbar .nav a.active, .navbar .nav a.active:hover, .navbar .nav a.active:focus' – knownasilya

+0

此解決方案最終不會使用打破瀏覽器中常用鏈接功能的A標記 – alexspeller

6

大廈,您可以在單擊導航元素的parentViewactive屬性被重新計算。

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() 
}); 
+0

這是一個好的開始,但是當您刷新頁面時,活動類不見了。 –

+2

當你在'this._super()'下設置'this.notifyPropertyChange('active');'刷新的問題是固定的。 –

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'); 
     }); 
    } 
}); 
1

您可以跳過延伸的視圖,並使用以下。

{{#linkTo "index" tagName="li"}}<a>Homes</a>{{/linkTo}} 

即使沒有href Ember.JS仍然會知道如何掛鉤LI元素。

+0

此解決方案離開鏈接沒有HREF打破通常的瀏覽器交互(右鍵點擊以在新窗口中打開,複製網址等) – alexspeller

5

我剛纔寫的組件,使這個更好一點:

App.LinkLiComponent = Em.Component.extend({ 
    tagName: 'li', 
    classNameBindings: ['active'], 
    active: function() { 
    return this.get('childViews').anyBy('active'); 
    }.property('[email protected]') 
}); 

Em.Handlebars.helper('link-li', App.LinkLiComponent); 

用法:

{{#link-li}} 
    {{#link-to "someRoute"}}Click Me{{/link-to}} 
{{/link-li}} 
+0

你能解釋這是如何工作的嗎?我有一個關於它的問題 – sunrize920

0

在寫作時當前的答案的日期。在較新版本的Ember中,如果您使用的是{{link-to}},噹噹前路由匹配目標鏈接時,它會自動在<a>元素上設置'active'類。

所以,只需編寫您的css,期望<a>將有active,它應該開箱即用。

添加了幸運功能。所有這些之前需要解決這個「問題」的東西都非常荒謬。

9

嗯,我採取了什麼@alexspeller偉大的想法,並把它轉換到燼-CLI:

應用程序/組件/鏈路li.js

export default Em.Component.extend({ 
    tagName: 'li', 
    classNameBindings: ['active'], 
    active: function() { 
     return this.get('childViews').anyBy('active'); 
    }.property('[email protected]') 
}); 

在我的Navbar我:

{{#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}} 
+0

非常感謝你!我無法弄清楚如何使用ember-cli – sunrize920

+2

在Glimmer時代用'childViews'祝你好運。 –

相關問題