【问题标题】:How to log values of @Input/@Output values by custom decorator如何通过自定义装饰器记录@Input/@Output 值的值
【发布时间】:2020-09-28 21:11:21
【问题描述】:

我试图通过简单地提供/使用自定义装饰器来记录我的组件传入(输入)和传出(输出)的每个值。我只是没有达到可以读取/打印一些值的地步。

自定义装饰器

function Log() {
  return (target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log('this: ', this) // this: undefined
    console.log('target: ', target) // target: Object { constructor: f FooComponent() }
    console.log('propertyKey: ', propertyKey) // propertyKey: source
    console.log('descriptor: ', descriptor) // descriptor: undefined
    return descriptor;
  }
}

组件

export class FooComponent  {
  // This observable just emits 'one', 'two' and 'three' one by one.
  public source$ = of(['one', 'two', 'three']).pipe(
    mergeMap(identity)
  )

  // Wanted usage (if possible)
  @Output() @Log() source = this.source$;
}

控制台中的预期输出

one
two
three

@Output() 装饰器仍然有效,我得到了从FooComponent 发出的值。但我不知道如何读出正在通过这个装饰器的变量,甚至不知道如何从中读取值。我已经尝试过Log的以下正文:

  • this[propertyKey](这里我收到一个错误,因为无法读取未定义的属性)
  • target[propertyKey](这里我只收到未定义的)

如果您需要测试设置:stackblitz

【问题讨论】:

  • here。特别是在它开始引用reflect-metadata的部分;页面的下半部分..
  • 使用 rxjs 有更好的替代方法来拦截 observables,decorator 似乎不太适合在这里使用。
  • @FanCheung 我正在使用其他方法来记录值​​。在使用水龙头的管道中。 getter/setter 的装饰器。功能的装饰器。这个问题实际上只是关于输入/输出的装饰器。对我来说,如果技术上不可能的话,也可以。
  • 我认为这在技术上是可行的,但实现起来可能很棘手,请看这里dev.to/angular/decorators-do-not-work-as-you-might-expect-3gmj 由于您的实例属性是可观察的,因此您需要 .pipe 另一个记录器来拦截流.

标签: javascript angular typescript rxjs decorator


【解决方案1】:

感谢@FanCheung,他的文章参考为我提供了构建装饰器的正确知识。

日志装饰器

function Log(): any {
  return (target, propertyKey, propertyDescriptor) => {
    const key = Symbol();
    return {
      get() {
        return this[key]; 
      },
      set(newValue: Observable<any>) {
        console.log(newValue);
        this[key] = newValue.pipe(
          tap(v => console.error(`${String(propertyKey)}: `, v))
        );
        if (propertyDescriptor) {
          propertyDescriptor.set(newValue);
        }
      }
    }
  }
}

用法

// Class with decorator usage
class Foo {
  private readonly source$ = of('baz');
  @Output() @Log() source = this.source$
}

// Usage of Foo as <foo>
<foo (source)="..."></foo>

// Expected output
source: baz

说明

可以在文章Decorators do not work as you might expect 中找到有关实际情况的深入见解。

【讨论】:

    猜你喜欢
    • 2018-02-14
    • 2021-03-30
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多