2

我有一个带有视口属性的组件。我想监听此属性的更改,进行一些计算并将可能更改的值反映回属性。我的第一次尝试看起来像这样:

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。有什么好主意吗?

4

1 回答 1

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()做同样事情的。

于 2018-09-10T14:13:01.327 回答