J'ai besoin de combiner des assistants linkTo et action dans Ember.js. Mon code est:
{{#link-to 'index'}}<span {{action 'clear'}}>Clear</span>{{/link-to}}
Mais je voudrais faire quelque chose comme ça:
{{#link-to 'index' {{action 'clear'}} }}Clear{{/link-to}}
Et aussi:
<li>
{{#link-to 'support'}}
<span {{action 'myAction' 'support'}}>Support</span>
{{/link-to}}
</li>
À:
<li>
{{#link-to 'support' {{action 'myAction' 'support'}} }}Support{{/link-to}}
</li>
Comment puis-je atteindre cet objectif?
Vérifiez ma réponse pour Ember 2.0 compatible, OK pour la solution de référencement.
J'ai récemment développé cet addon pour résoudre ce problème avec le style Ember 2.0 - 2.14+ compatible (1.13 fonctionne également!) Et en tirant parti des actions/noms d'action de clôture. C'est bon pour le référencement!
ember install ember-link-action
Vous pouvez transmettre une action de fermeture en tant que invokeAction
param à {{link-to}}
composant:
{{#link-to 'other-route' invokeAction=(action 'testAction')}}
Link to another route
{{/link-to}}
Vous pouvez également utiliser le nom de l'action au lieu de l'action de fermeture:
{{#link-to 'other-route' invokeAction='testAction'}}
Link to another route
{{/link-to}}
Pour passer des paramètres à l'action, vous pouvez utiliser:
{{#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)}}
Link to another route
{{/link-to}}
La suite de tests automatisés confirme que l'addon fonctionne avec les versions 1.13 et Ember 3 les plus récentes.
Il fonctionne avec une version, une version bêta et une version canari d’Ember.
Addon GitHub référentiel. Les contributions sont les bienvenues.
Mise à jour: Voir le commentaire de Michael Lang ci-dessous pour Ember 1.8.1+.
Le problème avec la réponse de Myslik (ne pas utiliser link-to
du tout mais utiliser plutôt un action
puis un transitionToRoute
) est que c'est inutile pour le référencement , les moteurs de recherche ne verront rien.
Si vous voulez que votre lien pointe vers l'indexation, il est plus facile d'avoir un bon vieux <a href=x>
dedans. Il est préférable d'utiliser link-to
pour que vos URL de lien restent synchronisées avec les URL de votre itinéraire. La solution que j'utilise donne à la fois une action pour faire le travail et un link-to
pratique pour indexer les pages.
Je remplace certaines fonctionnalités de 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);
}
});
Ensuite, je peux spécifier quelle action exécuter et quoi transmettre dans le guidon:
<span {{action 'view' this}}>
{{#link-to 'post' action='view' actionParam=this}}
Post Title: {{title}}
{{/link-to}}
</span>
Dans le contrôleur:
App.PostsIndexController = Ember.ArrayController.extend({
actions: {
view: function(post){
this.transitionToRoute('post', post);
}
}
}
Ainsi, lorsque je mets en cache une copie rendue de la page et que je la sers à un bot d'indexation, celui-ci voit un lien réel avec une URL et le suit.
(notez également que transitionTo
est maintenant déconseillé en faveur de transitionToRoute
)
Aucune de ces combinaisons ne fonctionnera dans Ember.js, mais vous n’avez pas besoin de combiner ces deux aides. Pourquoi n'utilisez-vous pas simplement Action Helper et laissez-vous en bulle au contrôleur ou à la route? Là, vous pouvez utiliser transitionToRoute
dans le contrôleur ou transitionTo
dans route.
Par exemple, dans le contrôleur, vous pourriez avoir un code comme celui-ci:
App.PostsController = Ember.ArrayController.extend({
clear: function () {
// implement your action here
this.transitionToRoute('index');
}
});
Cela fonctionne très bien dans 1.6.0-beta.5:
<span {{action "someAction"}}>
{{#link-to "some.route"}}
Click Me
{{/link-to}}
</span>
Le lien se produira et le clic sera affiché au gestionnaire d’actions. C'est documenté (même indirectement) ici .
Edit: syntaxe corrigée lors de l'ouverture de la balise link
J'aime l'approche de Cereal Killer pour sa simplicité, mais malheureusement, cela pose un problème pour moi. Lorsque le navigateur navigue vers un autre itinéraire, il redémarre l'application Ember .
Depuis Ember 2.6, l'approche simple suivante fait l'affaire:
<span {{action 'closeNavigationMenu'}}>
{{#link-to 'home' preventDefault=false}}
Go Home
{{/link-to}}
</span>
Cela permet d'atteindre les objectifs suivants:
Ayant le même problème, j'ai trouvé cette solution simple:
{{#linkTo eng.rent class="external-button"}}<div class="internal-button" {{action "updateLangPath"}} >X</div>{{/linkTo}}
puis, gérant le bouton external et le bouton internal de la classe CSS dans la feuille de style, je me suis assuré que le "bouton interne" couvrait toute la zone "external-button"; De cette manière, il n'est pas possible de cliquer sur le bouton externe sans cliquer sur le bouton interne.
Cela fonctionne bien pour moi. espérons que cela peut aider ...
Voici comment j'ai résolu ce problème dans notre application de démonstration du livre O'Reilly Ember.js: https://github.com/emberjsbook .
Vous pouvez voir la source complète ici: https://github.com/emberjsbook/rocknrollcall
Dans la vue:
{{#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}}
Et le contrôleur:
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: []
});
Les balises link-to d'Ember utilisent des routes pour ouvrir de nouvelles vues. Vous pouvez ainsi exécuter la fonctionnalité que vous souhaitez insérer dans l'attribut "action" du lien dans la méthode setupController
de la route cible plutôt que dans une action du contrôleur.
Voir ici dans le guide Ember: http://emberjs.com/guides/routing/setting-up-a-controller/
Cela ne fonctionne que si vous souhaitez exécuter l'action à chaque fois que vous accédez à l'itinéraire, par opposition à des liens spécifiques.
Assurez-vous d'inclure la ligne controller.set('model', model);
avec tout ce que vous avez mis dedans.