Объединить linkTo и помощники действий в Ember.js
Мне нужно объединить linkTo и помощники действий в Ember.js. Мой код:
{{#link-to 'index'}}<span {{action 'clear'}}>Clear</span>{{/link-to}}
Но я хотел бы сделать это примерно так:
{{#link-to 'index' {{action 'clear'}} }}Clear{{/link-to}}
А также:
<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>
Как я могу это достичь?
Решение
Проверьте мой ответ на Ember 2.0, OK для решения для SEO.
Ответы
Ответ 1
Ember Link Action addon
Это нормально для SEO решения !
Установить аддон
ember install ember-link-action
использование
Вы можете передать действие закрытия как параметр invokeAction
{{link-to}}
:
{{#link-to 'other-route' invokeAction=(action 'testAction')}}
Link to another route
{{/link-to}}
Для передачи параметров в действие вы можете использовать:
{{#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)}}
Link to another route
{{/link-to}}
Совместимость
Автоматизированный набор тестов подтверждает, что аддон работает с 1.13 до последних выпусков Ember 3.
Работает с выпуском, бета и канарскими версиями Ember.
Аддон GitHub хранилище. Вклад приветствуется.
Ответ 2
Обновление: См. комментарий Майкла Ланга ниже для Ember 1.8.1 +
Проблема с Myslik отвечает (не используя link-to
вообще, а вместо этого используя action
, а затем transitionToRoute
) заключается в том, что он бесполезен для SEO, боты поисковых систем ничего не видят.
Если вы хотите, чтобы ваша ссылка указывала на индексацию, проще всего иметь старый добрый <a href=x>
. Лучше всего использовать link-to
, чтобы ваши URL-адреса ссылок синхронизировались с вашими URL-адресами маршрута. Решение, которое я использую, дает как действие для выполнения работы, так и удобный link-to
для индексации страниц.
Я переопределяю некоторые функции 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);
}
});
Затем я могу указать, какое действие принять и что передать действие в Handlebars:
<span {{action 'view' this}}>
{{#link-to 'post' action='view' actionParam=this}}
Post Title: {{title}}
{{/link-to}}
</span>
В контроллере:
App.PostsIndexController = Ember.ArrayController.extend({
actions: {
view: function(post){
this.transitionToRoute('post', post);
}
}
}
Таким образом, когда я кэширую визуализированную копию страницы и подаю ее на индексный бот, бот увидит реальную ссылку с URL-адресом и последует за ней.
(обратите внимание также, что transitionTo
теперь устарел в пользу transitionToRoute
)
Ответ 3
Ни одна из этих комбинаций не будет работать в Ember.js, но вам не нужно комбинировать эти два помощника. Почему бы вам просто не использовать помощник действий и не допустить его до контроллера или маршрута? Там вы можете использовать transitionToRoute
в контроллере или transitionTo
в пути.
Например, в контроллере у вас может быть такой код:
App.PostsController = Ember.ArrayController.extend({
clear: function () {
// implement your action here
this.transitionToRoute('index');
}
});
Ответ 4
Это отлично работает в версии 1.6.0-beta.5:
<span {{action "someAction"}}>
{{#link-to "some.route"}}
Click Me
{{/link-to}}
</span>
Связь будет происходить, а затем щелчок будет обработан обработчиком действий. Он документировал (хотя и косвенно) здесь.
Изменить: исправленный синтаксис при открытии тега ссылки
Ответ 5
Мне нравится подход Cereal Killer для его простоты, но, к сожалению, у меня есть проблема для меня. Когда браузер переходит на другой маршрут, он перезапускает приложение Ember.
Как и в Ember 2.6, следующий простой подход делает трюк:
<span {{action 'closeNavigationMenu'}}>
{{#link-to 'home' preventDefault=false}}
Go Home
{{/link-to}}
</span>
Это достигается следующим образом:
- перемещается по маршруту 'home'
- действие 'closeNavigationMenu' вызывается
- при наведении указателя мыши, браузер отобразит ссылку, которая будет соблюдаться (для SEO и лучшего UX).
- Навигация браузера не приводит к перезагрузке приложения Ember
Ответ 6
Имея ту же проблему, я нашел это простое решение:
{{#linkTo eng.rent class="external-button"}}<div class="internal-button" {{action "updateLangPath"}} >X</div>{{/linkTo}}
затем, управляя внешними кнопками класса css и внутренней кнопкой в таблице стилей, я убедился, что "внутренняя кнопка" покрывала всю область "внешних кнопок"; таким образом, невозможно щелкнуть по внешней кнопке, не нажимая на внутреннюю кнопку.
Это хорошо работает для меня; надеюсь, что это может помочь...
Ответ 7
Вот как я решил это в нашем демо-приложении для книги O'Reilly Ember.js: https://github.com/emberjsbook.
Здесь вы можете увидеть полный источник: https://github.com/emberjsbook/rocknrollcall
В представлении:
{{#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}}
И контроллер:
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: []
});
Ответ 8
Использование меток для ссылок на теги использует маршруты для открытия новых представлений, поэтому вы можете выполнять любую функциональность, которую вы хотите поместить в атрибут "действие" в методе setupController
целевого маршрута, а не в действие контроллера.
См. здесь в руководстве Ember:
http://emberjs.com/guides/routing/setting-up-a-controller/
Это работает только в том случае, если вы хотите выполнять действие каждый раз при доступе к маршруту, в отличие от конкретных ссылок.
Обязательно включите строку controller.set('model', model);
вместе с тем, что вы там положили.