Примечание. sendAction не рекомендуется в пользу действий по закрытию. Вот RFC: https://github.com/emberjs/rfcs/pull/335. Вы также можете прочитать о Действиях по закрытию здесь.

Некоторых из нас может немного запутать использование send и sendAction в компонентах Ember. Я бы попытался объяснить, как send и sendActions взаимодействуют с контроллерами и маршрутами, приведя несколько примеров распространенных ошибок, с которыми вы можете столкнуться.

Предположим, нам нужно обработать следующие случаи:

  1. Передача данных от компонента к его контроллеру / маршруту.
  2. Передача данных от контроллера на его маршрут.
  3. Передача данных из вложенного компонента в его родительский компонент.

Ember следует соглашению под названием «Data Down Actions Up» или, как известно, подходу DDAU. Что это обозначает? Проще говоря, мы должны отправлять данные вниз и запускать действия.

Из основ работы с Ember мы знаем, что это router.js, который является точкой входа для определения того, какой маршрут / контроллер / шаблон должен быть вызван.

Предположим, у нас есть маршрут под названием foo.show. Наш файл маршрутизатора - routes / foo / show.js и, при необходимости, контроллер с тем же соглашением об именах контроллеры / foo / show.js. Когда маршрут создается (через ember g), Ember CLI также создает шаблон в пути templates / foo / show.hbs. Допустим, у нас есть компонент {{foo-bar}}, который будет отображаться в нашем шаблоне show.hbs. Вот так будет выглядеть структура нашего проекта

1. Передача данных от компонента к его контроллеру / маршруту:

Если вы хотите обмениваться данными от компонента к его контроллеру / маршруту, вы просто вызываете sendAction (). Помнить! sendAction () можно использовать из компонента, но не из контроллеров / маршрутов.

// component/foo-bar.js
export default Ember.Component.extend({
  actions: {
    sendDataToController() {
      this.sendAction('sendData', 1);
    }
  }
});
// controllers/foo/show.js
export default Ember.Controller.extend({
  actions: {
    sendData(data) {
      alert(data);
    }
  }
});
// routes/foo/show.js
export default Ember.Route.extend({
});

ПРИМЕЧАНИЕ. Если вы хотите инициировать действие в маршруте от компонента, вы можете просто выполнить тот же код, что и выше, и в этом случае контроллер не должен иметь действие.

// component/foo-bar.js
export default Ember.Component.extend({
  actions: {
    sendDataToController() {
      this.sendAction('sendData', 1);
    }
  }
});
// controllers/foo/show.js
export default Ember.Controller.extend({
});
// routes/foo/show.js
export default Ember.Route.extend({
  actions: {
    sendData(data) {
      alert(data);
    }
  }
});

Ознакомьтесь с Github GIST и Ember twiddle здесь.

2. Передача данных от контроллера на его маршрут.

Если вы хотите связаться с контроллером по его маршруту, вы просто вызываете send (). Здесь sendAction () работать не будет!

// component/foo-bar.js
export default Ember.Component.extend({
  actions: {
    sendDataToController() {
      this.sendAction('sendData', 1);
    }
  }
});
// controllers/foo/show.js
export default Ember.Controller.extend({
 actions: {
    sendData(data) {
      alert("Data is sent to controller as " + data + ". Will now send to route");
      this.send('sendDataToRoute', data);
    }
  }
});
// routes/foo/show.js
export default Ember.Route.extend({
  actions: {
    sendDataToRoute(data) {
      alert("Data sent to route" + data);
    }
  }
});

Но приведенное выше не имеет смысла, поскольку действия, отсутствующие в Controller, будут внутренне распространяться на его маршрут.

// component/foo-bar.js
export default Ember.Component.extend({
  actions: {
    sendDataToController() {
      this.sendAction('sendData', 1);
    }
  }
});
// controllers/foo/show.js
export default Ember.Controller.extend({
// Can remove this actions.
  actions: {
    sendData(data) {
      alert("Data is sent to controller as " + data + ". Will now send to route");
      return true;
    }
  }
});
// routes/foo/show.js
export default Ember.Route.extend({
  actions: {
    sendData(data) {
      alert("Data sent to route" + data);
    }
  }
});

ПРИМЕЧАНИЕ. Когда вы общаетесь от контроллера к его маршруту, мантра состоит в том, чтобы просто вызвать this.send ().

Ознакомьтесь с Github GIST и Ember twiddle здесь.

3. Передача данных из вложенного компонента в его родительский компонент.

Если вы хотите обмениваться данными от компонента к его родительскому компоненту, следует использовать вызов sendAction ().

// templates/foo-bar.hbs
{{foo-bar-2 sendDataToParent='sendDataToParent'}}
// component/foo-bar.js
export default Ember.Component.extend({
  actions: {
    sendDataToParent(data) {
      alert('Data received ' + data);
    }
  }
});
// component/foo-bar2.js
export default Ember.Component.extend({
  actions: {
    sendDataToParent() {
      this.sendAction('sendDataToParent', 1);
    }
  }
});

Что, если вы хотите запустить действие на своем пути?

Все, что вам нужно сделать, это просто выполнить шаг 2. Но для этого есть надстройка Ember, которая распространит ваше действие с foo-bar2 на маршрут routes / foo-bar / show.js под названием тлеющий маршрут-действия-помощник .

ПРИМЕЧАНИЕ. Если вы хотите запустить действие в самом foo-bar2, вы вызываете this.send (), а не this.sendAction ().

Ознакомьтесь с Github GIST и Ember twiddle here.

Если вам понравился этот пост или вы нашли что-то вводящее в заблуждение, оставьте свои комментарии!