将“活动”类分配给 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】:
活动路线的路径通过currentPath
在ApplicationController
中自动更新,所以我在我的应用程序中做了类似的事情......
在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" <a bindAttr href="view.href">Dives</a> /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 列表,即我的应用程序中的<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 知道何时(重新)评估该属性。
希望有帮助
【讨论】:
【参考方案12】:我去了:
Ember.LinkView.reopen(
didInsertElement:function()
if(this.$().hasClass('active'))
this.$().parent().addClass('active');
);
我不想使用已接受的答案,因为我想将我的 li 元素保留为普通的旧 html。可能有更好的方法来检查活动状态,但我无法访问正确的属性。
【讨论】:
当您在应用中导航时这将不起作用以上是关于将“活动”类分配给 EmberJS 中的选定列表项的主要内容,如果未能解决你的问题,请参考以下文章