Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine linkTo and action helpers in Ember.js

I need to combine linkTo and action helpers in Ember.js. My code is:

{{#link-to 'index'}}<span {{action 'clear'}}>Clear</span>{{/link-to}} 

But I would like to make this something like this:

{{#link-to 'index' {{action 'clear'}} }}Clear{{/link-to}} 

And also:

<li>     {{#link-to 'support'}}         <span {{action 'myAction' 'support'}}>Support</span>     {{/link-to}} </li> 

To:

<li>     {{#link-to 'support' {{action 'myAction' 'support'}} }}Support{{/link-to}} </li> 

How can I achieve this?

Solution

Check my answer for Ember 2.0 compatible, OK for SEO solution.

like image 610
Daniel Kmak Avatar asked Apr 20 '13 19:04

Daniel Kmak


2 Answers

Ember Link Action addon

This is OK for SEO solution!

Install addon

ember install ember-link-action 

Usage

You can pass closure action as invokeAction param to {{link-to}} component:

{{#link-to 'other-route' invokeAction=(action 'testAction')}}   Link to another route {{/link-to}} 

To pass parameters to action you can use:

{{#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)}}   Link to another route {{/link-to}} 

Compatibility

Automated test suite confirms that addon works with 1.13 up to latest Ember 3 releases.

It works with a release, beta and canary versions of Ember.

Addon GitHub repository. Contributions are welcome.

like image 146
Daniel Kmak Avatar answered Sep 18 '22 03:09

Daniel Kmak


Update: See Michael Lang's comment below for Ember 1.8.1+

The problem with Myslik's answer (not using link-to at all but instead using an action and then transitionToRoute) is that it's useless for SEO, search engine bots will see nothing.

If you want what your link is pointing to to be indexed, it's easiest to have a good old <a href=x> in there. It's best to use link-to so that your link URLs are kept in sync with your route URLs. The solution I use gives both an action to do the work and a handy link-to to index the pages.

I override some functionality of Ember.LinkView:

Ember.LinkView.reopen({   action: null,   _invoke: function(event){     var action = this.get('action');     if(action) {       // There was an action specified (in handlebars) so take custom action       event.preventDefault(); // prevent the browser from following the link as normal       if (this.bubbles === false) { event.stopPropagation(); }        // trigger the action on the controller       this.get('controller').send(action, this.get('actionParam'));       return false;      }                 // no action to take, handle the link-to normally     return this._super(event);   } }); 

Then I can specify which action to take and what to pass the action in Handlebars:

<span {{action 'view' this}}>   {{#link-to 'post' action='view' actionParam=this}}     Post Title: {{title}}   {{/link-to}} </span> 

In the controller:

App.PostsIndexController = Ember.ArrayController.extend({   actions: {     view: function(post){       this.transitionToRoute('post', post);     }   } } 

This way, when I cache a rendered copy of the page and serve that to an indexing bot, the bot will see a real link with an URL and follow it.

(note also that transitionTo is now deprecated in favour of transitionToRoute)

like image 20
Noland Avatar answered Sep 17 '22 03:09

Noland