我有一个带有视口属性的组件。我想听听对此属性的更改,进行一些计算并将可能更改的值反映回该属性。我的第一次尝试看起来像这样:
class MyComponent {
@Prop()
viewport: ViewportData
@Watch('viewport)
viewportChanged(newValue: ViewportData, oldValue:ViewportData) {
... do some calculations
// Reflect value back as property
this.viewport = computedViewport;
}
}
这会导致堆栈溢出,因为将值反射回来会触发另一个对watch函数的调用。我可以通过标有这是否是内部更改的标志来阻止它。像这样:
class MyComponent {
internalViewportChange = false;
@Prop()
viewport: ViewportData
@Watch('viewport)
viewportChanged(newValue: ViewportData, oldValue:ViewportData) {
if (this.internalViewportChange) {
this.internalViewportChange = false;
return;
}
... do some calculations
// Reflect value back as property
this.internalViewportChange = true;
this.viewport = computedViewport;
}
}
我不喜欢这种方法。并且正在寻找更好的东西。通常可以通过使用getter和setter以及保留实际状态的私有变量来解决此问题:
class MyComponent {
private _viewport: ViewportData
get viewport() {
return this._viewport;
}
set viewport() {
... do some calculations
// Reflect value back as property
this.viewport = computedViewport;
}
}
但是,使用Stenciljs会自动生成getter和setter。有什么好主意吗?
答案 0 :(得分:1)
我可能会打破双向道具设置,并且 创建单向数据流,并发出事件。像这样:
class MyComponent
@Event() viewportChanged: EventEmitter;
@Prop() viewport: ViewportData;
@State() _computedViewport: ViewportData;
@Watch('viewport') onViewportChanged(newValue) {
// do calculations
this._computedViewport = computedViewport;
this.viewportChanged.emit(this._computedViewport);
}
在内部,您只能在_computedViewport
上工作,而公共viewportProp
仅在此处供用户更新。表面上,您还可以公开执行相同操作的@Method()
。