如果特定路径处于活动状态,我该如何渲染块?

时间:2013-08-12 15:02:31

标签: ember.js

如果特定路线处于活动状态,我只想在Ember Handlebars中渲染一个块。 那么,我如何创建一个'ifRoute'帮助器,使用与'linkTo'帮助器上的'active'类相同的条件?

我想要这个,因为我有两层导航。因此,如果头部导航点处于活动状态,我只想显示子导航。我不想使用'active'类,因为我使用延迟加载,我只想在头导航点处于活动状态时加载子导航。

所以,我想做的是:

<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>

我该怎么做?还是有更好的解决方案?

由于

4 个答案:

答案 0 :(得分: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会做其余的事情

答案 1 :(得分: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 API定义与needs的依赖关系以收集访问权限,然后在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助手不支持块(在余烬手柄定制中),我使用了一个简单的帮助器,它不会根据你想要的绑定重新评估条件。

希望它有所帮助。

答案 2 :(得分:1)

在调查了linkTo的ember代码和helper之后,直觉像素和a blog post about writing my own bound block helper的答案,我找到了解决方案:

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);
});

答案 3 :(得分: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