【问题标题】:Assigning 'active' class to selected list item in EmberJS将“活动”类分配给 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() 无效。这让我觉得我做错了什么。

谢谢!

【问题讨论】:

    标签: ember.js


    【解决方案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 能够以某种方式自动将一个值推送到控制器中,然后又会绑定到
    • 的活动类,那就太好了。
  • 我找到的最接近的是这个解决方案:stackoverflow.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="active}}About{{/linkTo}}</li>
    <li >{{#linkTo "login" activeClass="active}}Login{{/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。可能有更好的方法来检查活动状态,但我无法访问正确的属性。

            【讨论】:

            • 当您在应用中导航时这将不起作用
            猜你喜欢
            相关资源
            最近更新 更多
            热门标签