Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I render a block only if a specific route is active?

Tags:

ember.js

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

like image 868
Lux Avatar asked Aug 12 '13 15:08

Lux


2 Answers

Just add to the controller:

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

Similarly:

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

I am quite sure latest Ember does the rest

like image 170
Vasyl Marchuk Avatar answered Sep 22 '22 14:09

Vasyl Marchuk


Here are two possible options, although for both you first have to save the currentPath in your ApplicationController to have access to it whenever you need it:

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

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

Using a computed property

Then in the controller backing up the template, let's say you have a NavigationController you create the computed property and define also the dependency to the ApplicationController with the needs API to gather access, then in the CP you check if the currentPath is the one you want:

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

So you can use a simple {{#if}} helper in your template:

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

Using a custom '{{#ifRoute}}' helper

But if your really want a custom helper to deal with your condition then this is how you could do it, note that the currentPath stored on your application is still needed since we need a way to get the value of the current route:

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

And then you could use it like this:

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

See here also a simple Demo of the "custom helper" solution: http://jsbin.com/izurix/7/edit

Note: with the second solution there is a catch! Since bound helpers do not support blocks (in embers handlebars customization) I used a simple helper that does not reevaluate the condition depending on bindings which is may not what you want.

Hope it helps.

like image 32
intuitivepixel Avatar answered Sep 20 '22 14:09

intuitivepixel