Как обработать действие в EmberJS во вложенном компоненте - PullRequest
0 голосов
/ 07 января 2019

, поэтому я вложил компоненты в EmberJS и не могу правильно обработать их действия.

У меня есть маршрут Create и в его шаблоне Компонент pixel-grid:

<div class="row">
    <div class="col-sm-7">
        {{pixel-grid}}
    </div>
    <div class="col-sm-5">

    </div>
</div>

В pixel-grid шаблоне у меня есть компонент с именем pixel-cell:

<table class="mx-auto">
    {{#each (range 0 panelWidth) as |row|}}
    <tr class="table-row">
        {{#each (range 0 panelHeight) as |cell|}}
        <th class="table-cell">
            {{pixel-cell onClick=(action 'changeColor')}}
        </th>
        {{/each}}
    </tr>
    {{/each}}
</table>

Компонент pixel-cell имеет пустой шаблон, так как он мне пока не нужен. В pixel-cell файле компонента js у меня есть:

import Component from '@ember/component';
export default Component.extend({
    classNames: ['cell', 'clickable'],
    tagName: 'div',

    init() {
        this._super(...arguments);
    },
});

Этот код явно не компилируется, так как я не выполнял это действие. Но ..

Я пытался установить действие в pixel-cell, но затем Эмбер сказала мне, что pixel-grid должно иметь это действие. Поэтому я поместил это changeColor действие в pixel-grid ->, которое не работает.

Итак, я попытался обработать что-то вроде этого в pixel-cell js:

click() {
    this.sendAction('changeColor');
},

-> это не работает.

Понятия не имею, как это должно работать; / Я пытался читать руководства, но все равно не справился. Пожалуйста, помогите.

Ответы [ 4 ]

0 голосов
/ 07 января 2019

Я бы рекомендовал не обрабатывать действия с компонентами. Вместо этого всегда используйте закрывающие действия!

Если вы делаете {{some-component onClick=(action 'changeColor')}}, вам нужно действие changeColor на соответствующем , а не внутри some-component! Однако вы, вероятно, захотите использовать его внутри some-component следующим образом:

<button onclick={{@changeColor}}>...</button>

В вашем случае я бы установил tagName: '' для компонента pixel-cell и добавил бы этот шаблон:

<div onclick={{@changeColor}}></div>
0 голосов
/ 07 января 2019

лично я никогда не пользовался sendAction. Вместо этого вы должны передавать действия в качестве атрибутов от родителей к дочерним компонентам, а затем вызывать их в дочерних компонентах. Этот подход гораздо легче рассуждать, а также о других преимуществах, которые https://emberigniter.com/send-closure-actions-up-data-owner/ объясняет в деталях.

В вашем примере:

пиксельные-grid.js:

export default Component.extend({
  actions: {
    changeColor(cell) {
      console.log("CELL ACTION");
      console.log(cell);
      cell.style.backgroundColor = 'red';
    }
  }
});

пиксел grid.hbs:

{{pixel-cell handleColorChange=(action 'changeColor')}}

пиксельные-cell.js:

export default Component.extend({
    classNames: ['cell', 'clickable'],
    tagName: 'div',

    click: function () {
        // Invoke parent action and pass this element as the argument
        this.get("handleColorChange")(this.element);
    }
});
0 голосов
/ 07 января 2019

https://ember -twiddle.com / e04e318489bcc8e9e921e849c9fb9e9e? OpenFiles = templates.components.pixel-cell.hbs% 2Ctemplates.components.pixel-grid.hbs

Я создал тиддл, чтобы показать вам пример действия, передаваемого от родительского компонента к дочернему компоненту. Вы можете сослаться на вышеупомянутый URL, чтобы понять это легче.

Вместо sendAction я использовал концепцию, называемую действиями закрытия, которая является нормой в Ember в будущем.

0 голосов
/ 07 января 2019

Хорошо, так что мне удалось заставить это работать. Это выглядит так:

pixel-grid шаблон:

<table class="mx-auto">
    {{#each (range 0 panelWidth) as |row|}}
    <tr class="table-row">
        {{#each (range 0 panelHeight) as |cell|}}
        <th class="table-cell">
            {{pixel-cell}}
        </th>
        {{/each}}
    </tr>
    {{/each}}
</table>

pixel-cell файл компонента js:

import Component from '@ember/component';
export default Component.extend({
    classNames: ['cell', 'clickable'],
    tagName: 'div',

    click: function () {
        this.sendAction('changeColor', this);
    },

    changeColor(cell) {
        console.log("CELL ACTION");
        console.log(cell);
        cell.element.style.backgroundColor = 'red';
    }
});

Другие файлы пусты (только высота панели и ширина панели в файле pixel-grid js). Это хороший способ сделать это?

...