Подтвердить что ты не робот

Объединить 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.

4b9b3361

Ответ 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); вместе с тем, что вы там положили.