Combine linkTo and action helpers in Ember.js

后端 未结 8 1880
隐瞒了意图╮
隐瞒了意图╮ 2020-12-13 13:50

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

{{#link-to \'index\'}}Clear{{/link-to}}


        
相关标签:
8条回答
  • 2020-12-13 14:28

    Having the same problem, i found this simple solution:

    {{#linkTo eng.rent class="external-button"}}<div class="internal-button" {{action "updateLangPath"}} >X</div>{{/linkTo}}
    

    then, managing the css classes external-button and internal-button in the stylesheet, i made sure that the "internal-button" was covering the whole "external-button" area; in this way it is not possible to click on the external-button without clicking on the internal-button.

    It works well for me; hope it can help...

    0 讨论(0)
  • 2020-12-13 14:37

    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)

    0 讨论(0)
  • 2020-12-13 14:40

    I like Cereal Killer's approach for its simplicity, but unfortunately it exhibits a problem for me. When the browser navigates to another route, it restarts the Ember application.

    As of Ember 2.6, the following simple approach does the trick:

    <span {{action 'closeNavigationMenu'}}> {{#link-to 'home' preventDefault=false}} Go Home {{/link-to}} </span>

    This achieves the following:

    • navigates to route 'home'
    • action 'closeNavigationMenu' is invoked
    • on mouseover, browser displays link that will be followed (for SEO and better UX)
    • browser navigation does not result in reboot of Ember app
    0 讨论(0)
  • 2020-12-13 14:41

    This is how I solved this in our demo application for the O'Reilly Ember.js book: https://github.com/emberjsbook.

    You can see the complete source here: https://github.com/emberjsbook/rocknrollcall

    In the view:

    {{#if artistsIsChecked}}
      {{#if artists.length}}
        <h3>Artists</h3>
    
        <ul class="search-results artists">
          {{#each artists}}
            <li><a {{action 'viewedArtist' this.enid }}>{{name}}</a></li>
          {{/each}}
        </ul>
      {{/if}}
    {{/if}}
    

    And the controller:

    App.SearchResultsController = Em.ObjectController.extend({
      actions: {
        viewedArtist: function(enid) {
          this.transitionToRoute('artist', enid);
        },
        viewedSong: function(sid) {
          this.transitionToRoute('song', sid);
        }
      },
      needs: ['artists', 'songs'],
      artistsIsChecked: true,
      songsIsChecked: true,
      artists: [],
      songs: []
    });
    
    0 讨论(0)
  • 2020-12-13 14:44

    None of these combinations will work in Ember.js, but you do not need to combine these two helpers. Why don't you just use action helper and let it bubble to controller or route? There you can use transitionToRoute in controller or transitionTo in route.

    For example in controller you could have code like this:

    App.PostsController = Ember.ArrayController.extend({
        clear: function () {
            // implement your action here
            this.transitionToRoute('index');
        }
    });
    
    0 讨论(0)
  • 2020-12-13 14:45

    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.

    0 讨论(0)
提交回复
热议问题