将“活动”类分配给EmberJS中的选定列表项

时间:2013-01-19 07:18:33

标签: ember.js

我有一个列表,我想自动将一个项目设置为class =“active”。给出以下引导代码:

<ul class="nav">
<li {{bindAttr class="atIndex:active"}}>{{#linkTo "index"}}Index{{/linkTo}}</li>
<li {{bindAttr class="atAbout:active"}}>{{#linkTo "about"}}About{{/linkTo}}</li>
<li {{bindAttr class="atLogin:active"}}>{{#linkTo "login"}}Login{{/linkTo}}</li>
</ul>

atIndex,atAbout和atLogin驻留在我的ApplicationController中。

渲染为:

<ul class="nav">
<li class="active"><a...>Index{{/linkTo}}</li>
<li><a...>About<a></li>
<li><a...>Login<a></li>
</ul>

使用Ember 1.0 pre4做到这一点的最佳方法是什么?我宁愿不为每个视图或控制器添加特殊代码。

PS - atIndex: true有效,但atIndex: function() {return true; }.property().volatile()没有。这让我觉得我做错了什么。

谢谢!

12 个答案:

答案 0 :(得分:75)

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

答案 1 :(得分:14)

到目前为止,解决此问题的最简洁方法是利用linkTo帮助程序的内置支持,在渲染链接时设置活动类。除了源代码之外,还没有记录AFAIK:

实施:https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/helpers/link_to.js#L46

示例:https://github.com/emberjs/ember.js/blob/master/packages/ember/tests/helpers/link_to_test.js#L120

要利用此功能,只需根据链接上的活动类而不是li元素将css调整为样式。如果您确实需要设置li的样式,则可以创建一个自定义视图和帮助,其扩展Ember.LinkView并使用li,但更改css会更容易。

---更新----

因为我们都喜欢twitter bootstrap 只是改变css 可能不是一个很好的选择。在这种情况下,以下将做到这一点:

App.ApplicationView = Ember.View.extend({
  currentPathDidChange: function() {
    Ember.run.next( this, function() {
      this.$("ul.nav li:has(>a.active)").addClass('active');
      this.$("ul.nav li:not(:has(>a.active))").removeClass('active');
    });
  }.observes('controller.currentPath')
});

使用ember linkTo helper和bootstrap pill的工作示例:http://jsbin.com/ekobod/5/edit(需要ember-1.0.0-pre.4)

答案 2 :(得分:5)

活动路径的路径会在ApplicationController中自动更新currentPath所以我在我的应用中做了类似的事情...... 在ApplicationController添加的属性如下:

isProductsActive: function(){
  if ( this.get('currentPath') === 'products' ) return 'active';
  else return '';
}.property('currentPath')

并在我的ApplicationView模板中:

<li {{bindAttr class="isProductsActive"}}>
  {{#linkTo "products"}}Products{{/linkTo}}
</li>

答案 3 :(得分:5)

我制作了一个处理此问题的ember-cli插件:

https://github.com/alexspeller/ember-cli-active-link-wrapper

答案 4 :(得分:3)

修改: 最后,我发现使用链接的ember.js使用bootstrap li元素的activate类的最佳方法。

{{#linkTo "dives" tagName="li"}}
   <a {{bindAttr href="view.href"}}>Dives</a>
{{/linkTo}}

-------------- 8&LT; --------------

<强>弃用:

我猜在Ember.js为linkTo helper引入activeClass属性之前,之前的答案是相关的。 现在我会解决这个问题:

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

Enber会在相关时自动添加课程。

答案 5 :(得分:2)

如果我可以提出另一个除了Handlebars之外只需要解决方案的解决方案:

<li {{bind-attr class="view.innerLink.active:active"}}>
    {{#link-to "path" viewName="innerLink"}}Click{{/link-to}}
</li>

这会将LinkView对象设置为父视图的成员,然后您可以引用它的活动属性。

答案 6 :(得分:2)

我在列表组(http://getbootstrap.com/components/#list-group-linked)中使用链接项找到了一个非常简单的解决方案。

<div class="list-group">
{{#each thing in list}}
    {{#link-to "details" thing.id tagName="a" href="view.href" class="list-group-item" {{thing.name}} {{/link-to}}
{{/each}}
</div>

适用于Bootstrap v3.1.1和Ember v1.7.0

答案 7 :(得分:2)

只需将{{link-to}}与tagName嵌套在外部。我在EmberJS 2.0上这样做。

{{1}}

答案 8 :(得分:1)

如果您想在Ember中使用Bootstrap导航,那么您可以使用Bootstrap for Ember,它具有开箱即用的支持:

Github:https://github.com/ember-addons/bootstrap-for-ember 演示:http://ember-addons.github.io/bootstrap-for-ember/dist/#/show_components/tabs

答案 9 :(得分:1)

很多这些答案已经过时了。这是Bootstrap和Ember 2.x的更清洁(和DRY)版本:

{{#link-to "index" tagName="li" as |link|}}
  <a href="#" class="{{if link.active 'active'}}">Index Page</a>
{{/link-to}}

答案 10 :(得分:0)

我通过为每个项目创建一个视图并使用classNameBindings解决了类似的问题(我必须说我没有HTML列表,即我的应用中的<a>...</a>,只是列表<div>)。

这是我的工作方式:

在tasklist.handlebars中,我遍历我的自定义视图

  {{#each tasks}}
    {{view App.TaskListItemView contentBinding="this"....}}
  {{/each}}

Ember会为每个项目插入一个视图(即<div>)。

每个项目的视图类在task_list_item_view.js中定义为

App.TaskListItemView = Ember.View.extend({

  controller: null,
  classNameBindings: ['isSelected', 'isClosed'],

  isClosed: function() {
      var content = this.get('content');
      return content && !content.isOpen(new Date);
  }.property('controller.content.@each'),

  isSelected: function() {
      return (this.get('controller').isSelectedTask(this.get('content')));
  }.property('controller.taskSelection.@each'),

  ....
});

最后,视图的模板只是在tasklistitem.handlebars

中呈现我的链接
<a {{action "selectTask" view.content target="view"}} rel="tooltip"
         {{bindAttr title="view.content.comment"}} class="taskListLink">
  ....
</a>

AFAIK您必须在property()调用中指定源数据,让ember知道何时(重新)评估该属性。

希望有所帮助

答案 11 :(得分:-1)

我去了:

 Ember.LinkView.reopen({
didInsertElement:function(){

    if(this.$().hasClass('active')){

        this.$().parent().addClass('active');

    }
}

});

我不想使用接受的答案,因为我想将我的li元素保持为普通的旧HTML。可能有更好的方法来检查活动状态,但我无法访问正确的属性。