51

我正在尝试创建导航选项卡(取自Twitter Bootstrap):

<ul class="nav nav-tabs">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">Profile</a></li>
    <li><a href="#">Messages</a></li>
</ul>

活动选项卡标有class="active"

http://jsfiddle.net/schawaska/pfbva/上有一个很好的静态导航栏和路由器/插座功能示例,但我不明白如何创建动态导航栏/菜单/选项卡视图。

据我了解,可以在每个菜单项中使用类绑定:

 classNameBindings: ['isActive:active']

但是切换 isActive 属性的正确位置在哪里?

4

15 回答 15

154

余烬 1.11+:

{{#link-to "dashboard" tagName="li"}}
  <a href="{{view.href}}">Dashboard</a>
{{/link-to}}

Ember < 1.11(bind-attr必需):

{{#link-to "dashboard" tagName="li"}}
  <a {{bind-attr href="view.href"}}>Dashboard</a>
{{/link-to}}
于 2013-01-24T12:08:23.630 回答
26

如果您使用的是 Ember >= 1.11,那么下面的https://stackoverflow.com/a/14501021/65542是正确答案。


我会创建一个NavigationView,请参阅http://jsfiddle.net/pangratz666/z8ssG/

车把

<script type="text/x-handlebars" data-template-name="navigation">
    <ul class="nav nav-tabs">
        {{#view view.NavItemView item="home" }}
            <a {{action gotoHome}} >Home</a>
        {{/view}}
        {{#view view.NavItemView item="profiles" }}
            <a {{action gotoProfiles}} >Profiles</a>
        {{/view}}
        {{#view view.NavItemView item="messages" }}
            <a {{action gotoMessages}} >Messages</a>
        {{/view}}        
    </ul>
</script>

JavaScript

App.NavigationView = Em.View.extend({
    templateName: 'navigation',
    selectedBinding: 'controller.selected',
    NavItemView: Ember.View.extend({
        tagName: 'li',
        classNameBindings: 'isActive:active'.w(),
        isActive: function() {
            return this.get('item') === this.get('parentView.selected');
        }.property('item', 'parentView.selected').cacheable()
    })
});

在您的路线内,connectOutlets您必须通过router.set('navigationController.selected', 'home');...设置当前导航项


还可以查看ember-bootstrap存储库,它在 Ember.js 中包装了 Bootstrap 的这个和更多功能

于 2012-07-24T11:34:07.610 回答
17

上面的一些建议对于 twitter bootstrap 案例仍然有效。你也可以试试这样的

{{#link-to 'dashboard' tagName='li'}} 
  {{#link-to 'dashboard'}}Link Title{{/link-to}}
{{/link-to}}
  1. link-towith tagName将li活动类应用于 li
  2. 内部link-to将是一个在右键单击时anchor为您提供功能的元素Open in New Tab
于 2014-05-31T05:17:43.827 回答
10

最近有一个 Ember-cli 插件可以做到这一点。它被称为ember-cli-active-link-wrapper

安装:ember install ember-cli-active-link-wrapper

你可以像这样使用它:

{{#active-link}}
  {{link-to "Index" "index"}}
{{/active-link}}

这导致:

<li class='active'>
    <a href="/" class='active'>Index</a>
</li>
于 2015-04-29T09:38:19.293 回答
7

我知道这是旧帖子,但这里是Ember 2.4.0的更新

要创建链接,您可以编写

{{#link-to 'photoGallery'}}
  Great Hamster Photos
{{/link-to}}

或者

{{link-to 'Great Hamster Photos' 'photoGallery'}}

当当前路由与链接的路由匹配时,Ember 会自动将类设置为活动状态(在本例中photoGallery)。

如果您还想控制其他路线上的“活动”类,您可以通过设置current-when属性来实现。

{{#link-to 'photoGallery' current-when='photoGallery photoPreview'}}
  Great Hamster Photos
{{/link-to}}

此链接将在和路线active上都有课程。photoGalleryphotoPreview

https://github.com/emberjs/ember.js/blob/v2.4.0/packages/ember-routing-views/lib/components/link-to.js#L140

于 2016-03-12T08:40:08.057 回答
4

车把

<ul class="nav">
    <li>{{#linkTo "index"}}Index{{/linkTo}}</li>
    <li>{{#linkTo "about"}}About{{/linkTo}}</li>
</ul>

Javascript

App.Router.map(function() {
    this.route("about");
});

它将根据路由自动添加活动类。注意:使用 ember-1.0.0-pre.4.js 测试

于 2013-02-16T12:51:09.023 回答
3

您还可以将 isActive 方法更改为如下内容:

isActive: function() {
    return App.getPath('router.currentState.path') === "root.firms";
}.property("App.router.currentState"),

或者

isActive: function() {
    return this.get('controller.target.currentState.path') === "root.firms";
}.property("controller.target.currentState"),
于 2012-08-02T07:08:15.587 回答
3

我看到这个问题已经很老了,但是如果您将 Ember.js 升级到 RC3,您可以使用tagName属性,例如:

{{#link-to messages tagName="li"}}Messages{{/link-to}}

这是 API - http://emberjs.com/api/classes/Ember.LinkView.html

于 2013-04-26T23:38:36.273 回答
1

不确定它是否非常动态,但尝试在http://codebrief.com/2012/07/anatomy-of-an-ember-dot-js-app-part-i-redux-routing-and-outlets/上查看解决方案 主要思想是检查您的应用程序的状态

JavaScript:

function stateFlag(name) {
  return Ember.computed(function() {
    var state = App.router.currentState;
    while(state) {
      if(state.name === name) return true;
      state = state.get('parentState');
    }
    return false;
  }).property('App.router.currentState');
}

ApplicationController: Ember.Controller.extend({
    isHome: stateFlag('home'),
    isSections: stateFlag('sections'),
    isItems: stateFlag('items')
  })

车把:

<li class="home" {{bindAttr class="isHome:active"}}>
</li>
<li class="sections" {{bindAttr class="isSections:active"}}>
</li>
<li class="items" {{bindAttr class="isItems:active"}}>
</li>

更新: pangratz 的解决方案看起来更漂亮

于 2012-07-24T11:14:26.437 回答
1

这是一个完整的工作解决方案:

看法:

App.NavView = Ember.View.extend({
  tagName: 'li',
  classNameBindings: ['active'],

  active: function() {
    return this.get('childViews.firstObject.active');
  }.property()
});

模板:

<ul>
  {{#each item in controller}}
  {{#view App.NavView}}
  {{#linkTo "item" item tagName="li"}}
      <a {{bindAttr href="view.href"}}>
        {{ item.name }}
      </a>
  {{/linkTo}}
  {{/view}}
  {{/each}}
</ul>
于 2013-02-14T21:20:04.083 回答
1

从 v0.8.0 开始,ember-bootstrap支持导航,包括正确处理活动状态。而且没有任何链接到/标签名称的黑客:

{{#bs-nav type="pills"}}
   {{#bs-nav-item}}
      {{#link-to "foo"}}Foo{{/link-to}}
   {{/bs-nav-item}}
   {{#bs-nav-item}}
     {{#link-to "bar"}}Bar{{/link-to}}
   {{/bs-nav-item}}
 {{/bs-nav}}

http://kaliber5.github.io/ember-bootstrap/api/classes/Components.Nav.html

于 2016-07-09T08:37:32.880 回答
1

此处提出的许多解决方案不适用于任何最近的 Ember 版本(例如,不推荐使用的视图)。此外,仅使用link-to帮助程序不会解决问题,因为引导程序希望active该类出现在<li>not <a>

因此,我将尝试总结目前确实有效的解决方案:

使用ember-cli-active-link-wrapper

该插件为此特殊用例提供了一个组件:

<ul class="nav nav-tabs">
  {{#active-link}}
    {{#link-to "foo"}}Foo{{/link-to}}
  {{/active-link}}
  {{#active-link}}
    {{#link-to "bar"}}Bar{{/link-to}}
  {{/active-link}}
</ul>

取自https://stackoverflow.com/a/29939821/5556104

使用ember-bootstrap

ember-bootstrap提供了许多将引导功能集成到您的 ember 应用程序中的组件,其中包括导航组件:

{{#bs-nav type="tabs"}}
   {{#bs-nav-item}}
      {{#link-to "foo"}}Foo{{/link-to}}
   {{/bs-nav-item}}
   {{#bs-nav-item}}
      {{#link-to "bar"}}Bar{{/link-to}}
   {{/bs-nav-item}}
 {{/bs-nav}}

取自https://stackoverflow.com/a/38279975/5556104

链接到黑客

有点hacky,但应该在没有任何额外插件的情况下工作:

<ul class="nav nav-tabs">
  {{#link-to "foo" tagName="li"}} 
    {{#link-to "foo"}}Foo{{/link-to}}
  {{/link-to}}
  {{#link-to "bar" tagName="li"}} 
    {{#link-to "bar"}}Bar{{/link-to}}
  {{/link-to}}
</ul>

取自https://stackoverflow.com/a/23966652/5556104

于 2016-07-28T10:54:35.223 回答
0

迟早想要更改您的状态的命名或您必须通过代码和视图的任何内容,还添加一个函数来 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
)

nav-view.hbs(用于 twitter-bootstrap 风格的导航)

<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'
    )
  ]
)
于 2012-12-27T19:18:04.320 回答
0

baijum 上面的回答大部分是正确的,但是在最新版本的 Ember 中,“bind-attr”已被弃用。这是编写它的新方法:

{{#link-to "dashboard" tagName="li"}}
    <a href="{{view.href}}">Dashboard</a>
{{/link-to}}

正如你所看到的,它更容易,而且有点像魔术一样的工作......

于 2015-07-21T16:35:03.780 回答
0

就像其他人说的那样,使用{{#link-to}}链接到现有的route,当该路由是当前 URL 时,{{#link-to}}将自动添加active到其 CSS 类。

请参阅Ember 问题 4387

于 2016-10-31T19:55:11.047 回答