typescript - 基于 Prop 值在 StencilJS 中的动态事件名称
我正在尝试使用 StencilJS 创建一个通用滑块组件。我的想法是将滑块 ID 作为 prop 传递,然后在滑块变化时将该 prop 用作事件名称。
问题是监听器没有捕捉到用 prop 名称发出的动态事件。我认为这可能与组件的生命周期有关,但我不确定。有何想法吗?
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()
}
.
.
.
答案#1
我认为更好的方法是将滑块的 ID 作为事件数据/细节发出,不过无论如何……
据我所知,监听器应该可以工作,但 @Event 装饰器可能不行。你可以尝试手动创建事件,使用 dispatchEvent 和 CustomEvent。
export class MySlider {
@Element() host: HTMLMySliderElement;
onValueChange(change) {
this.slider_value = change.value;
this.host.dispatchEvent(new CustomEvent(this.slider_id));
}
// ...
}
答案#2
据我所知,在 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');
