Нажмите события на Ember - PullRequest
       38

Нажмите события на Ember

0 голосов
/ 21 сентября 2018

Я открываю для себя EmberJS и начал мигрировать существующий веб-сайт в эту среду.У меня была проблема с выпадающим списком на основе Bootstrap.Эта проблема на самом деле помогла мне понять концепции Эмбер немного лучше, но у меня все еще есть некоторые вопросы.

Я использовал модуль ember-bootstrap для создания этого раскрывающегося списка (среди прочего), и вот чтокод должен быть:

{{#bs-dropdown as |dd|}}
  {{#dd.button}}
    Sort by
  {{/dd.button}}

  {{#dd.menu as |ddm|}}
    {{#ddm.item}}{{#ddm.link-to "index"}}Price low to high{{/ddm.link-to}}{{/ddm.item}}
    {{#ddm.item}}{{#ddm.link-to "index"}}Price high to low{{/ddm.link-to}}{{/ddm.item}}
  {{/dd.menu}}
{{/bs-dropdown}}

Теперь я хочу, чтобы какой-нибудь код JavaScript выполнялся, когда пользователь нажимает на один из элементов.После проверки документации модуля я нашел, где был определен компонент меню , и отредактировал его код следующим образом:

export default Component.extend({
  layout,
  classNameBindings: ['containerClass'],

  /* ... */

  actions: {
    // My addition
    sortByPrice(param){
      alert("sorting");
    },
    // End of the addition

    toggleDropdown() {
      if (this.get('isOpen')) {
        this.send('closeDropdown');
      } else {
        this.send('openDropdown');
      }
    },
  },
});

Затем я обновил файл hbs какследует:

{{#dd.menu as |ddm|}}
   {{#ddm.item action "sortByPrice" low_to_high}}

    {{#ddm.link-to "index"  action "sortByPrice" low_to_high}}
      Prix croissant
    {{/ddm.link-to}}

  {{/ddm.item}}
{{/dd.menu}}

Это не сработало, и именно поэтому вы добавили *action* к элементу link-to и аналогичным образом объявили действие над его файлом компонента.

import LinkComponent from '@ember/routing/link-component';

export default LinkComponent.extend({
  actions: {
    sortByPrice(param){
        alert("sorting");
      console.log("sorting");
      },
  },
});

Как видите, компонент *link-to* расширяет компонент LinkComponent .В конце концов я понял, что этот элемент не может обрабатывать события щелчка по умолчанию, как объяснено в этой теме .

Из-за разочарования я получил менее элегантный подход, который до сих поруловка:

{{#bs-dropdown id="sort" as |dd|}}
  {{#dd.button}}
    Sort by
  {{/dd.button}}

  {{#dd.menu as |ddm|}}
    {{#ddm.item action "sortByPrice" low_to_high}}
      <a
        class="dropdown-item"
        onclick="sortByPrice('low_to_high'); return false;"
        href="#"
      >
        Price low to high
      </a>
    {{/ddm.item}}
  {{/dd.menu}}
{{/bs-dropdown}}

Теперь вот мои вопросы:

  1. Почему определение действий как для файла компонентов, так и для hbs one не изменило результат?
  2. Почему LinkComponent не обрабатывает события щелчка по умолчанию?Я понимаю, что ссылка должна перенаправлять пользователей на новую страницу (которая до сих пор спорно), но событие DOM еще уволят, так же Ember намеренно игнорировать его и выбрать, чтобы не позволить разработчикам справиться с этим?Я хочу знать логику этого.
  3. Есть ли лучший подход, чем мое решение?

Спасибо.

1 Ответ

0 голосов
/ 21 сентября 2018

Спасибо за изучение EmberJS и за размещение красивого, явного вопроса!

Ваши ошибки

  1. Никогда не изменяйте код в папках node_modules/ и bower_components/.Если вам действительно нужно что-то исправить, вы можете сделать это в инициализаторе.Но в вашем случае использования не требуется исправление обезьян.

  2. Вы попытались определить действие в компоненте элемента меню, но применили его в родительском шаблоне.Это действие должно быть определено в компоненте / контроллере шаблона этого родителя.

  3. Этот неверный вызов:

    {{#ddm.link-to "index"  action "sortByPrice" low_to_high}}
    

    Вот проблемы:

    1. Компонент ddm.link-to должен создать ссылку на другой маршрут.Кажется, он не поддерживает передачу действия в него.

    2. Вы просто передаете кучу позиционных параметров компоненту.Если ddm.link-to поддерживает принятие действия, правильный вызов будет выглядеть следующим образом:

      {{#ddm.link-to "index" argName=(action "sortByPrice" low_to_high)}}
      

      В этом случае "index" является параметром позиции, а argName является именованным параметром.

    3. low_to_high без кавычек - это ссылка на свойство, определенное в текущей области.Вы, вероятно, имели в виду строку вместо: "low_to_high".

  4. Никогда не используйте JS-код в шаблоне напрямую.Это никогда не следует делать в Ember:

    <a onclick="sortByPrice('low_to_high'); return false;">
    

    Вместо этого передайте действие (определенное в локальной области: в компоненте или контроллере):

    <a onclick={{action 'sortByPrice' 'low_to_high'}}>
    

    Свойство onclickИмя не обязательно.Действие, определенное без свойства, подразумевает onclick (вам нужно указать имя свойства только в том случае, если вам нужно прикрепить действие к другому событию):

    <a {{action 'sortByPrice' 'low_to_high'}}>
    

    Для правильного оформления ссылки вбраузер, требуется атрибут href.Но вам не нужно передавать значение '#'.Символ хеша требовался в приложениях старой школы, чтобы ссылка не перезаписывала URL.Ember переопределяет перезапись URL для вас, поэтому вы можете просто передать пустой href.

    Вот последнее правильное использование:

    <a href {{action 'sortByPrice' 'low_to_high'}}>
    

Ответы наваши вопросы

  1. Почему определение действий как для файла компонентов, так и для hbs-файла не изменило результат?

Потому что выопределили их в разных областях.

Если вы определяете действие в app/components/foo-bar.js, действие должно применяться в app/templates/components/foo-bar.hbs.

Если вы определяете действие в app/controllers/index.js, действиедолжен применяться в app/templates/index.hbs.

Почему LinkComponent не обрабатывает события щелчка по умолчанию?Я понимаю, что ссылка должна перенаправлять пользователей на новую страницу (которая до сих пор спорно), но событие DOM еще уволят, так же Ember намеренно игнорировать его и выбрать, чтобы не позволить разработчикам справиться с этим?Я хочу знать логику, лежащую в основе этого.

В PWA вы не выполняете фактические перенаправления страниц.Такое перенаправление перезагрузило бы все приложение.

Вместо этого LinkComponent отменяет щелчок и говорит системе маршрутизации Ember выполнить переход.Маршруты должны быть настроены правильно, и маршрут, передаваемый на LinkComponent, должен существовать.

Кажется, что ваша цель не в том, чтобы выполнить переход, а в том, чтобы изменить переменную, поэтому LinkComponent здесь не применимо,Это происходит только в том случае, если вы связываете свойство порядка сортировки с параметром запроса URL-адреса, и в этом случае вы можете изменить порядок сортировки, перейдя к другому параметру запроса.

Есть ли лучший подход, чем мое решение?

Ниже приведен самый простой подход, использующий раскрывающийся список ember-bootstrap.


Работающийпример

Контроллер:

export default Ember.Controller.extend({
  isSortAccending: true,

  actions: {
    changeSortDirection (isSortAccending) {
      this.set('isSortAccending', isSortAccending);
    }
  }
});

Шаблон:

<p>
  Current sort order:
  {{if isSortAccending "ascending" "descending"}}
</p>

{{#bs-dropdown as |dd|}}
  {{#dd.button}}
    Sort by
  {{/dd.button}}

  {{#dd.menu as |ddm|}}
    {{#ddm.item}}
      <a href {{action "changeSortDirection" true}}>
        Price high to low
      </a>
    {{/ddm.item}}

    {{#ddm.item}}
      <a href {{action "changeSortDirection" false}}>
        Price high to low
      </a>
    {{/ddm.item}}
  {{/dd.menu}}
{{/bs-dropdown}}

Вот рабочая демонстрация .

...