如何使用新的Ember路由器绑定到链接的活动类?

Nic*_*gaz 22 ember.js

我在我的Ember.js应用程序中使用Twitter Bootstrap进行导航.Bootstrap activeli包含导航链接的标记上使用类,而不是active在链接本身上设置类.

Ember.js的新linkTo助手将active在链接上设置一个类,但(据我所见)并不提供任何挂钩到该属性.

现在,我正在使用这种丑陋的方法:

{{#linkTo "inbox" tagName="li"}}
  <a {{bindAttr href="view.href"}}>Inbox</a>
{{/linkTo}}
Run Code Online (Sandbox Code Playgroud)

这将输出:

<li class="active" href="/inbox"><a href="/inbox">Inbox</a></li>
Run Code Online (Sandbox Code Playgroud)

这是我想要的,但不是有效的HTML.

我还尝试active从父视图绑定到生成的LinkView 属性,但如果这样做,父视图将在插入之前呈现两次,从而触发错误.

除了手动重新创建linkTo助手内部使用的逻辑以将active类分配给链接之外,还有更好的方法来实现这种效果吗?

Yeh*_*atz 27

我们肯定需要一个更公开,永久的解决方案,但这样的事情现在应该有效.

模板:

<ul>
{{#view App.NavView}}
  {{#linkTo "about"}}About{{/linkTo}}
{{/view}}

{{#view App.NavView}}
  {{#linkTo "contacts"}}Contacts{{/linkTo}}
{{/view}}
</ul>
Run Code Online (Sandbox Code Playgroud)

视图定义:

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

  active: function() {
    return this.get('childViews.firstObject.active');
  }.property()
});
Run Code Online (Sandbox Code Playgroud)

这取决于几个约束:

  • 导航视图包含单个静态子视图
  • 你可以使用你<li>的视图.关于如何从JavaScript定义或Handlebars自定义视图元素的文档中有很多细节.

我已经提供这个工作的实时JSBin.

  • 将'childViews.firstObject.active'添加到Yehuda的jsbin中的property()调用中为我修复了它.这是工作:http://jsbin.com/apisic/1/edit (6认同)
  • 这似乎不起作用(不再?) - 它触发了"你试图在渲染后重新渲染视图但在它插入DOM之前"错误.我的hack-ish解决方案仍然有效. (5认同)

Ada*_*ein 9

好吧,我采取了@alexspeller的好主意并将其转换为ember-cli:

应用/组件/链路li.js

export default Em.Component.extend({
    tagName: 'li',
    classNameBindings: ['active'],
    active: function() {
        return this.get('childViews').anyBy('active');
    }.property('childViews.@each.active')
});
Run Code Online (Sandbox Code Playgroud)

在我的导航栏中,我有:

{{#link-li}}
    {{#link-to "squares.index"}}Squares{{/link-to}}
{{/link-li}}
{{#link-li}}
    {{#link-to "games.index"}}Games{{/link-to}}
{{/link-li}}
{{#link-li}}
    {{#link-to "about"}}About{{/link-to}}
{{/link-li}}
Run Code Online (Sandbox Code Playgroud)

  • 祝你在Glimmer时代的'childViews`好运. (2认同)

pjl*_*tyn 8

您还可以使用嵌套的链接到:

{{#link-to "ccprPracticeSession.info" controller.controllers.ccprPatient.content content tagName='li' href=false eventName='dummy'}}
  {{#link-to "ccprPracticeSession.info" controller.controllers.ccprPatient.content content}}Info{{/link-to}}
{{/link-to}}
Run Code Online (Sandbox Code Playgroud)


Ili*_*oly 6

基于katz的答案,您可以在单击activenav元素时重新计算属性parentView.

App.NavView = Em.View.extend({

    tagName: 'li',
    classNameBindings: 'active'.w(),

    didInsertElement: function () {
        this._super();
        var _this = this;
        this.get('parentView').on('click', function () {
            _this.notifyPropertyChange('active');
        });
    },

    active: function () {
        return this.get('childViews.firstObject.active');
    }.property()
});
Run Code Online (Sandbox Code Playgroud)

  • 当你在`this._super()'下设置`this.notifyPropertyChange('active');`时,刷新的问题是固定的. (2认同)

ale*_*ler 5

我刚刚编写了一个组件来使它更好一些:

App.LinkLiComponent = Em.Component.extend({
  tagName: 'li',
  classNameBindings: ['active'],
  active: function() {
    return this.get('childViews').anyBy('active');
  }.property('childViews.@each.active')
});

Em.Handlebars.helper('link-li', App.LinkLiComponent);
Run Code Online (Sandbox Code Playgroud)

用法:

{{#link-li}}
  {{#link-to "someRoute"}}Click Me{{/link-to}}
{{/link-li}}
Run Code Online (Sandbox Code Playgroud)