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

I want to make a block only in Ember Handlebars handles if a specific route is active. So, how can I create an ifRoute helper with the same conditions as the "active" class in the "linkTo" helper?

I want this because I have two-layer navigation. Thus, I want to show only navigation if the head navigation point is active. I do not want to use the โ€œactiveโ€ class because I use lazy loading, and only want to load sub-navigation when the head navigation point is active.

So, I want to do the following:

<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

+7
source share
4 answers

After learning the ember code for linkTo and if helps the answer from intuitivepixel and a blog post about writing my own linked block helper , I found a solution:

 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); }); 
+1
source share

Just add a 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'm sure the last amber does the rest

+7
source share

Here are two possible options, although for both you first need to store the currentPath in the ApplicationController in order to access it when 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 that backs up the template, let's say that you have a NavigationController , you create a computed property and also determine the dependence on the ApplicationController with API needs to collect access, and then in CP you check if the currentPath 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 the Special '{{#ifRoute}}' Helper

But if you really want the user assistant to deal with your state, then you can do this, note that the currentPath stored in your application is still necessary, 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 can use it as follows:

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

See also a simple demo of a "custom assistant" solution: http://jsbin.com/izurix/7/edit

Note: there is a catch with the second solution! Since bound helpers do not support blocks (in the settings for coal handles), I used a simple assistant that does not overestimate the condition depending on the bindings, which may not be what you need.

Hope this helps.

+4
source share

I found a simple way to check if a route is active, but getting it into a computed property may not be so simple.

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

For use:

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

+1
source share

All Articles