Stenciljs 自定义事件未通过@Listen 响应
Stenciljs custom event not responding via @Listen
我正在尝试了解自定义事件发射器的流程。我有鼠标事件工作的滚动代码,但不是自定义事件。通过开发工具跟踪它,它正在发射但没有被听众接收到。
顶级组件在这里:
import { Component, Prop, Listen, State, Event, EventEmitter } from "@stencil/core"
@Component ({
tag: "control-comp"
})
export class SmsComp1 {
@Prop() compTitle:string;
@State() stateData: object = {name: "Fred"};
@Event() stateChanged: EventEmitter;
@Listen('inBox')
inBoxHandler(ev) {
console.log('In box', ev);
this.stateData["name"] = ev.name;
console.log('Emitting')
this.stateChanged.emit(this.stateData);
}
render () {
let index = [1, 2, 3, 4, 5]
return (
<div>
<h1>{this.compTitle}</h1>
{index.map( (i) => {
return <my-component first={i.toString()} last="Don't call me a framework" width={i*40} height={i*40}></my-component>
})}
<my-component first={this.stateData["name"]} last="'Don't call me a framework' JS"></my-component>
</div>
)
}
}
组件在这里:
import { Component, Prop, Listen, State, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Prop() first: string;
@Prop() last: string;
@Prop() width: number = 120;
@Prop() height: number = 100;
@State() colour: string = 'red';
@Event() inBox: EventEmitter;
@Listen('mouseover')
clickHandler() {
this.colour = 'white';
this.inBox.emit({action: 'IN_BOX',
name: this.first+' '+this.last})
}
@Listen('mouseout')
mouseOutHandler() {
this.colour = 'red';
}
@Listen('stateChanged')
stateChangedHandler(state) {
console.log('Received', state);
}
render() {
return (
<svg width={this.width+10} height={this.height+10}>
<rect width={this.width} height={this.height} fill='green'></rect>
<circle cx={this.width/2} cy={this.height/2} r={this.width*0.1} fill={this.colour}></circle>
<text fill='white' x='10' y='10'>{this.first+' '+this.last}</text>
</svg>
);
}
}
index.html 终于来了:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
<title>Stencil Component Starter</title>
<script src="/build/mycomponent.js"></script>
</head>
<body>
<control-comp compTitle="Stencil Example"></control-comp>
<my-component first="My Dead" last='Component' width=100 height=120></my-component>
</body>
</html>
你能说说为什么 my-component
没有注意到 stateChanged 事件吗?
Stencil 事件,与其他 CustomEvent
s 一样,只会冒泡 向上 组件树,而不是向下冒泡。
由于 my-component
是 control-comp
的 child,control-comp
无法看到 parent 的 stateChanged
事件。
您需要找到另一种方法让 parent 与 child 组件通信。 "standard" 的方法是在 child 上设置一个 @Prop
或者 @Watch
,然后更新 parent 的 render()
函数。
或者,您可以使用更稳健的方法,例如 stencil-redux or stencil-state-tunnel。
也许为时已晚,但您可以使用 @Listen
的选项
export interface ListenOptions {
target?: 'parent' | 'body' | 'document' | 'window';
capture?: boolean;
passive?: boolean;
}
(来源:https://stenciljs.com/docs/events#listen-s-options)
如果您将侦听器附加到 document
,您将获得预期的事件
@Listen('inBox', { target: 'document' })
...
我正在尝试了解自定义事件发射器的流程。我有鼠标事件工作的滚动代码,但不是自定义事件。通过开发工具跟踪它,它正在发射但没有被听众接收到。
顶级组件在这里:
import { Component, Prop, Listen, State, Event, EventEmitter } from "@stencil/core"
@Component ({
tag: "control-comp"
})
export class SmsComp1 {
@Prop() compTitle:string;
@State() stateData: object = {name: "Fred"};
@Event() stateChanged: EventEmitter;
@Listen('inBox')
inBoxHandler(ev) {
console.log('In box', ev);
this.stateData["name"] = ev.name;
console.log('Emitting')
this.stateChanged.emit(this.stateData);
}
render () {
let index = [1, 2, 3, 4, 5]
return (
<div>
<h1>{this.compTitle}</h1>
{index.map( (i) => {
return <my-component first={i.toString()} last="Don't call me a framework" width={i*40} height={i*40}></my-component>
})}
<my-component first={this.stateData["name"]} last="'Don't call me a framework' JS"></my-component>
</div>
)
}
}
组件在这里:
import { Component, Prop, Listen, State, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Prop() first: string;
@Prop() last: string;
@Prop() width: number = 120;
@Prop() height: number = 100;
@State() colour: string = 'red';
@Event() inBox: EventEmitter;
@Listen('mouseover')
clickHandler() {
this.colour = 'white';
this.inBox.emit({action: 'IN_BOX',
name: this.first+' '+this.last})
}
@Listen('mouseout')
mouseOutHandler() {
this.colour = 'red';
}
@Listen('stateChanged')
stateChangedHandler(state) {
console.log('Received', state);
}
render() {
return (
<svg width={this.width+10} height={this.height+10}>
<rect width={this.width} height={this.height} fill='green'></rect>
<circle cx={this.width/2} cy={this.height/2} r={this.width*0.1} fill={this.colour}></circle>
<text fill='white' x='10' y='10'>{this.first+' '+this.last}</text>
</svg>
);
}
}
index.html 终于来了:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
<title>Stencil Component Starter</title>
<script src="/build/mycomponent.js"></script>
</head>
<body>
<control-comp compTitle="Stencil Example"></control-comp>
<my-component first="My Dead" last='Component' width=100 height=120></my-component>
</body>
</html>
你能说说为什么 my-component
没有注意到 stateChanged 事件吗?
Stencil 事件,与其他 CustomEvent
s 一样,只会冒泡 向上 组件树,而不是向下冒泡。
由于 my-component
是 control-comp
的 child,control-comp
无法看到 parent 的 stateChanged
事件。
您需要找到另一种方法让 parent 与 child 组件通信。 "standard" 的方法是在 child 上设置一个 @Prop
或者 @Watch
,然后更新 parent 的 render()
函数。
或者,您可以使用更稳健的方法,例如 stencil-redux or stencil-state-tunnel。
也许为时已晚,但您可以使用 @Listen
export interface ListenOptions {
target?: 'parent' | 'body' | 'document' | 'window';
capture?: boolean;
passive?: boolean;
}
(来源:https://stenciljs.com/docs/events#listen-s-options)
如果您将侦听器附加到 document
,您将获得预期的事件
@Listen('inBox', { target: 'document' })
...