Angular String Safe 和 NgOnchanges 组件中的 NameOf

Angular NameOf in Component for String Safe and NgOnchanges

比较 NgOnChanges 的最佳方法是什么,同时使其在 Angular 中 String 类型安全 ?目前这就是我正在做的。

NgOnChanges SimpleChanges 变量的数据类型为:any 并接受任何变量名,即使拼写错误也是如此。试图找到防止这种情况的干净方法。

原文:

else if (changes?.product?.previousValue != changes?.product?.currentValue) {
    this.submitSearch();

新:

export const nameof = <T>(name: keyof T) => name;

public readonly productMember = nameof<WebStoreSearchComponent>("product");

if ((changes[this.productMember]?.previousValue != changes[this.productMember]?.currentValue) {
    this.submitSearch();

Angular 是否有任何本机方法来执行此操作?

资源:

https://schneidenbach.gitbooks.io/typescript-cookbook/content/nameof-operator.html

注意:Getters/setters 不是解决方案,因为专门询问了 ngonchanges 的字符串安全。

去年我看到 this video from ngConf, which suggested an approach of using decorator 类似的东西,我觉得很有趣。可能对你有帮助。

想法是创建一个装饰器并将其用于所有需要的更改回调。

changes.decorator.ts

export function OnChanges<T>(callback: (newValue: T) => void) {
  const cachedValueKey = Symbol();
  return function(target, key) {
    Object.defineProperty(target, key, {
      set: function(value) {
        if (this[cachedValueKey] === value) {
          return;
        }

        this[cachedValueKey] = value;
        callback.call(this, value);
      },
      get: function() {
        return this[cachedValueKey];
      }
    });
  };
}

在您的案例中的用法:

@OnChanges<string>((newValue: string) => {
  this.submitSearch();
})
@Input()
productMember: string;

看看this stackblitz

Angular 中没有 built-in 对此的支持。一项功能请求已于 2017 年提交,目前仍在处理中:https://github.com/angular/angular/issues/17560

您可能希望为您的项目采用该线程中发布的一些解决方法,作为自定义解决方案。

使用 getter/setter 属性是 ngOnChanges 的一个很好的替代方法。

// tslint:disable-next-line: variable-name
private _productMember: string;

get productMember(): string {
  return this._productMember;
}
@Input()
set productMember(value: string) {
  const changed = value !== this._productMember;

  this._productMember = value;

  if (changed) {
    this.submitSearch();
  }
}