Dynami c Имена событий в трафарете JS на основе значения Prop - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь создать общий компонент слайдера, используя Stencil JS. Идея заключалась в том, чтобы передать идентификатор слайдера в качестве опоры, а затем использовать опору как имя события при изменении ползунка.

Проблема в том, что слушатели не улавливают события Dynami c, генерируемые с именами свойств. Я думаю, что это может быть связано с жизненным циклом компонента, но я не уверен. Есть идеи?

export class ParentComponent{

    @Listen('slider_A')
    onSliderValueChangeA(){
        console.log('event A') //not logging on slider change
    }

    @Listen('slider_B')
    onSliderValueChangeB(){
        console.log('event B') //not logging on slider change
    }

    @Listen('slider_C')
    onSliderValueChangeC(){
        console.log('event C')//not logging on slider change
    }

    render(){
        return (
            <div class='container'>
                <slider-input slider_id={'slider_A'} slider_title={'S1'} ></slider-input>
                <slider-input slider_id={'slider_B'} slider_title={'S2'} ></slider-input>
                <slider-input slider_id={'slider_C'} slider_title={'S3'} ></slider-input>
            </div>
        );
    }
}

Here is the slider component...

@Component({
    tag: 'slider-input',
    styleUrl: 'slider-input.scss',
    shadow: true
})

export class Slider{
    @Prop() slider_id: string;


    @Event({
        eventName: this.slider_id,
    }) on_slider_value_change: EventEmitter<null>;


    onValueChange(change){
        this.slider_value = change.value;
        this.on_slider_value_change.emit()
    }
.
.
.

Ответы [ 2 ]

0 голосов
/ 23 июня 2020

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

Слушатели должны работать, а декоратор @Event - нет. Вместо этого вы можете попробовать создать события вручную, используя dispatchEvent и CustomEvent.

export class MySlider {
  @Element() host: HTMLMySliderElement;

  onValueChange(change) {
    this.slider_value = change.value;

    this.host.dispatchEvent(new CustomEvent(this.slider_id));
  }

  // ...
}
0 голосов
/ 20 июня 2020

Насколько я знаю, имена событий Dynami c невозможны в Stencil, возможно, потому что имя события интерпретируется до загрузки компонента.

Вместо этого вы можете прикрепить слушателей непосредственно к элементам:

export class Slider {
    @Prop() slider_id: string;

    @Event() valueChange: EventEmitter<null>;

    onValueChange(change){
        this.slider_value = change.value;
        this.valueChange.emit()
    }
]
export class ParentComponent{

    onSliderValueChange(id: string){
        console.log('event', id)
    }

    render(){
        return (
            <div class='container'>
                <slider-input slider_id={'slider_A'} onValueChange={() => this.onSliderValueChange('A')} slider_title={'S1'} ></slider-input>
                <slider-input slider_id={'slider_B'} onValueChange={() => this.onSliderValueChange('B')} slider_title={'S2'} ></slider-input>
                <slider-input slider_id={'slider_C'} onValueChange={() => this.onSliderValueChange('C')} slider_title={'S3'} ></slider-input>
            </div>
        );
    }
}

Или вы можете добавить слушателя вручную:

@Element() el: HTMLElement;

this.el.querySelector('slider-input').addEventListener('valueChange', e => {
  switch(e.currentTarget.slider_id) {
    case 'slider_A':
      console.log('event A');
      break;
    case 'slider_B':
      console.log('event B');
      break;
  }
});

// or

this.el.querySelector('slider-input[slider_id=slider_A]')
  .addEventListener('valueChange', () => console.log('event A');
...