8

I wanna render a block in Ember Handlebars only, if a specific route is active. So, how can I create a 'ifRoute' helper, with the same conditons then the 'active' class on the 'linkTo' helper?

I want this, because I've a two layer navigation. So, I want to show the sub-navigation only, if the head navigation point is active. I dont wanna use the 'active' class, because I use lazy loading and I only want to load the sub navigation when the head navigation point is active.

So, what I want to do is:

<ul>
    {{#each assortmentGroups}}
        <li>
            {{#linkTo "assortmentGroup" this}} {{description}} {{/linkTo}}
            {{#ifRoute "assortmentGroup" this}}
                <ul>
                    {{#each itemCategories}}
                        <li>{{#linkTo "itemCategory" this}} {{description}} {{/linkTo}}</li>
                    {{/each}}
                </ul>
            {{/ifRoute}}
        </li>
    {{/each}}
<ul>

How can I do this or is there a better solution?

Thanks

4

4 回答 4

8

只需添加到控制器:

needs: ['application'], 
isCorrectRouteActive: Ember.computed.equal('controllers.application.currentRouteName', 'correctRoute')

相似地:

isCorrectPathActive: Ember.computed.equal('controllers.application.currentPath', 'correct.path')
isCorrectURLActive: Ember.computed.equal('controllers.application.currentURL', 'correctURL')

我很确定最新的 Ember 会完成其余的工作

于 2014-06-28T06:40:59.583 回答
4

这里有两个可能的选项,但对于这两个选项,您首先必须将其保存currentPath在您的文件ApplicationController中,以便在需要时访问它:

var App = Ember.Application.create({
  currentPath: ''
});

App.ApplicationController = Ember.ObjectController.extend({
  updateCurrentPath: function() {
    App.set('currentPath', this.get('currentPath'));
  }.observes('currentPath')
});

使用计算属性

然后在备份模板的控制器中,假设您有一个NavigationController创建计算属性并ApplicationController使用needsAPI 定义对 的依赖项以收集访问权限,然后在 CP 中检查是否currentPath是您想要的:

App.NavigationController = Ember.Controller.extend({
  needs: 'application',
  showSubMenu: function(){
    var currentPath = this.get('controllers.application.currentPath');
    return (currentPath === "assortmentGroup");
  }.property('controllers.application.currentPath')
});

所以你可以在你的模板中使用一个简单的{{#if}}助手:

...
{{#linkTo "assortmentGroup" this}} {{description}} {{/linkTo}}
  {{#if showSubMenu}}
    <ul>
      {{#each itemCategories}}
        <li>{{#linkTo "itemCategory" this}} {{description}} {{/linkTo}}</li>
      {{/each}}
    </ul>
  {{/if}}
</li>
...

使用自定义 '{{#ifRoute}}' 助手

但是,如果您真的想要一个自定义助手来处理您的情况,那么您可以这样做,请注意currentPath仍然需要存储在您的应用程序中,因为我们需要一种方法来获取当前路由的值:

Ember.Handlebars.registerHelper('ifRoute', function(value, options) {
  if (value === App.get('currentPath')) {
    return options.fn(this);
  }
  else {
    return options.inverse(this);
  }
});

然后你可以像这样使用它:

...
  {{#linkTo "assortmentGroup" this}} {{description}} {{/linkTo}}
  {{#ifRoute "assortmentGroup"}}
    <ul>
      {{#each itemCategories}}
        <li>{{#linkTo "itemCategory" this}} {{description}} {{/linkTo}}</li>
      {{/each}}
    </ul>
  {{/ifRoute}}
</li>
...

另请参阅此处的“自定义助手”解决方案的简单演示:http: //jsbin.com/izurix/7/edit

注意:使用第二种解决方案有一个问题!由于bound助手不支持块(在 embers 车把定制中),我使用了一个简单的助手,它不会根据绑定重新评估条件,这可能不是您想要的。

希望能帮助到你。

于 2013-08-12T16:24:39.287 回答
1

在调查了 linkTo 和 if 助手的 ember 代码、来自直观像素的答案和一篇关于编写我自己的绑定块助手的博客文章之后,我找到了一个解决方案:

var resolveParams = Ember.Router.resolveParams;

var resolvedPaths = function(options) {
    var types = options.options.types.slice(1),
    data = options.options.data;

    return resolveParams(options.context, options.params, { types: types, data: data });
};

Ember.Handlebars.registerHelper('ifRoute', function(name) {
    var options = [].slice.call(arguments, -1)[0];
    var params = [].slice.call(arguments, 1, -1);
    var theResolvedPaths = resolvedPaths({ context: this, options: options, params: params });
    var router = options.data.keywords.controller.container.lookup('router:main');

    var self = this;
    var evaluateIsCurrentRoute = function() {
        self.set('current_route_is_active_bool_for_ifroute', (function() {
            return router.isActive.apply(router, [name].concat(theResolvedPaths)) ||
                router.isActive.apply(router, [(name + '.index')].concat(theResolvedPaths));
        })());
    };

    evaluateIsCurrentRoute();
    router.addObserver('url', evaluateIsCurrentRoute);

    options.contexts = null;

    return Ember.Handlebars.helpers.boundIf.call(this, 'current_route_is_active_bool_for_ifroute', options);
});
于 2013-08-13T12:22:58.020 回答
1

我找到了一种检查路由是否处于活动状态的简单方法,但是将其放入计算属性可能并不那么容易。

// Test if you are currently in a route by it's lowercase name
App.isInRoute = function(name) {
    return App.Router.router.currentHandlerInfos.mapProperty('name').contains(name);
}

要使用:

App.isInRoute('posts.show'); // true if in the route

于 2014-04-02T08:36:10.330 回答