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

Posted

技术标签:

【中文标题】将“活动”类分配给 EmberJS 中的选定列表项【英文标题】:Assigning 'active' class to selected list item in EmberJS 【发布时间】:2013-01-02 22:33:00 【问题描述】:

我有一个列表,我想自动将一项设置为 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() 无效。这让我觉得我做错了什么。

谢谢!

【问题讨论】:

【参考方案1】:
#link-to "dashboard" tagName="li" href=false
  <a bind-attr href="view.href">
    Dashboard
  </a>
/link-to

【讨论】:

是的,如果你添加 href=false 到链接,这实际上会生成有效的 html。 :-) 这里有一个解决方法:只需重复里面的链接,你就会有 li 上的活动类和锚点中的 href:#linkTo "dashboard" tagName="li" href =false#linkTo "dashboard"Dashboard/linkTo/linkTo 我想最好的办法是编写自己的视图,但在我的情况下,它是一个纯静态的部分,而不是值得。 对于较新版本的 Ember,请务必使用 link-to 而不是 linkTo view 变量从何而来? 存在绑定属性view.href 的文档在哪里?我好像找不到。【参考方案2】:

到目前为止,解决这个问题的最简洁的方法是利用 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 with bootstrap pills 的工作示例:http://jsbin.com/ekobod/5/edit(需要 ember-1.0.0-pre.4)

【讨论】:

不幸的是,对于这个问题,我在我的项目中使用了流行的 javascript-bootstrap 控件。 (不过幸运的是,因为它们真的很棒。:-) 如果 linkTo 能够以某种方式自动将一个值推送到控制器中,然后又会绑定到 的活动类,那就太好了。 我找到的最接近的是这个解决方案:***.com/questions/14328295/… 有一个新的 pull-request 解决方案将 linkTo 标签包装在一个 li 中,可能想看看并评论github.com/emberjs/ember.js/pull/1849 那里的东西很整洁。我提交了this one,但它并不那么受欢迎。谢谢! 这个函数currentPathDidChange只在路径深度改变时运行。不是在同一级别发生变化时:从/pages/1/pages/2【参考方案3】:

活动路线的路径通过currentPathApplicationController 中自动更新,所以我在我的应用程序中做了类似的事情...... 在ApplicationController 中添加了如下属性:

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

在我的ApplicationView 模板中:

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

【讨论】:

这是个好主意。但是我会添加很多 项,并且我正在寻找一个更通用的解决方案,我可以将其应用于所有这些项,而无需每个链接都使用特殊的外壳。【参考方案4】:

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

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

【讨论】:

这个解决方案对我来说是最好的。许多嵌套的链接建议要么不再显示链接地址,要么显示常规光标而不是指针。【参考方案5】:

编辑: 最后,我发现使用链接的 ember.js 使用 bootstrap li 元素的激活类的最佳方法。

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

-------------8

已弃用:

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

<ul class="nav">
<li >#linkTo "index" activeClass="active"Index/linkTo</li>
<li >#linkTo "about" activeClass="activeAbout/linkTo</li>
<li >#linkTo "login" activeClass="activeLogin/linkTo</li>
</ul>

Enber 会在相关时自动添加类。

【讨论】:

不,问题是关于将活动类添加到 列表项,而不是链接。 是的,我知道,但是在 link 中使用已经内置的帮助器比构建复杂的逻辑来在 list 项中产生效果更有意义 i>... 除非 OP 想要修改特定的 list item DOM 属性。 @user11012 感谢您的回复 - 尽管它可能没有完全回答所提出的问题,但了解它非常有用 - 我没有,您为我节省了一些时间 :)跨度> @user11012,当您使用像 Bootstrap 这样的前端框架时,它没有更多意义,它在 li 项上使用“活动”类,而不是链接本身。 好的,这是我发现的 ember.js 使用引导功能的方法:code #linkTo "dives" tagName="li" &lt;a bindAttr href="view.href"&gt;Dives&lt;/a&gt; /linkTo【参考方案6】:

如果我可以建议另一种只需要把手的解决方案:

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

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

【讨论】:

与涉及 bind-attr 和 view.href 的其他解决方案相反,这实际上仍然适用于 Ember 1.12 和 HTMLbars!您可以使用 class=view.innerLink.active。【参考方案7】:

我找到了一个非常简单的解决方案,使用列表组中的链接项目 (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

【讨论】:

【参考方案8】:

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

#link-to "admin.websocket" tagName="li"
    #link-to "admin.websocket"WebSocket/link-to
/link-to

【讨论】:

【参考方案9】:

如果你想在 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

【讨论】:

【参考方案10】:

其中很多答案都已过时。这是 Bootstrap 和 Ember 2.x 的更干净(和 DRY)的版本:

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

【讨论】:

这不起作用。似乎 link 未定义。 WTF?!【参考方案11】:

我通过为每个项目创建一个视图并使用classNameBindings 解决了类似的问题(我不得不说我没有 HTML 列表,即我的应用程序中的&lt;a&gt;...&lt;/a&gt;,只有&lt;div&gt; 的列表) .

这是对我有用的方式:

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

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

Ember 将为每个项目插入一个视图(即&lt;div&gt;)。

每个项目的视图类在 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 知道何时(重新)评估该属性。

希望有帮助

【讨论】:

【参考方案12】:

我去了:

 Ember.LinkView.reopen(
didInsertElement:function()

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

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

    

);

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

【讨论】:

当您在应用中导航时这将不起作用

以上是关于将“活动”类分配给 EmberJS 中的选定列表项的主要内容,如果未能解决你的问题,请参考以下文章

emberjs - 如何使用路由器基础设施标记活动菜单项

活动菜单项 - asp.net mvc3 母版页

悬停列表项上的引导导航栏删除类活动,鼠标移出返回类活动

将列表框的选定项传递到 xaml

如何将列表框选定项作为按钮中的命令参数传递?

从 Android 中的 StartActivityForResult 返回一个类