【问题标题】:Parameterize method for initializing variables in typescript class用于在打字稿类中初始化变量的参数化方法
【发布时间】:2018-07-23 15:58:57
【问题描述】:

我的constructor 中有以下代码来初始化变量。

public Elements: Observable<dcElementDataStoreItem>;
private elementSubjectData: BehaviorSubject<dcElementDataStoreItem>;

constructor() {
  this.elementSubjectData = new BehaviorSubject([]) as BehaviorSubject<ElementDataStoreItem>;
  this.Elements = this.elementSubjectData.asObservable();
}

现在只有 2 行,我可能有几个类似的项目。 那么我可以做类似下面代码的事情吗,(但这不起作用)

constructor() {
  this.initSubjectData<dcElementDataStoreItem>(this.elementSubjectData, this.Elements);
}

private initSubjectData<T>(privateList: BehaviorSubject<T>, publicList: Observable<T>) {
  privateList = new BehaviorSubject([]) as BehaviorSubject<T>;
  publicList = privateList.asObservable();
}

这样我就可以重用这个initSubjectData 来初始化所有其他可能的方法

【问题讨论】:

    标签: angular typescript initialization code-reuse modularity


    【解决方案1】:

    您不能像在其他语言中那样“通过引用”传递字段,但您可以改为传递字段名称并通过索引进行访问。由于 Typescript 支持类型是另一种类型的键的概念,因此这将是类型安全的。

    public elementSubjectData: BehaviorSubject<ElementDataStoreItem>;
    public Elements: Observable<ElementDataStoreItem>;
    constructor() {
        this.initSubjectData("elementSubjectData", "Elements");
    }
    
    private initSubjectData(privateListField: keyof this, publicListField:  keyof this) {
        let privateList =  new BehaviorSubject([]);
        this[privateListField] = new BehaviorSubject([]) as any;
        this[publicListField] = privateList.asObservable() as any;
    }
    

    这种方法有两个问题:

    1. 没有关于字段类型的检查
    2. 属性必须是公开的,才能使字段成为keyofthis

    如果我们添加第二个函数来返回字段的类型表示,我们可以修复数字 1:

    interface Field<TName, TType> {
        name: string;
        set(value: TType) : void;
    }
    // In the class
    constructor() {
        this.initSubjectData(this.field("elementSubjectData"), this.field("Elements"));
    }
    field<TKey extends keyof this>(name: TKey): Field<TKey, this[TKey]> {
        return {
            name,
            set: (value) => {
                this[name] = value
            }
        };
    }
    private initSubjectData<T>(privateListField: Field<keyof this, BehaviorSubject<T>>, publicListField:  Field<keyof this, Observable<T>>) {
        let privateList = new BehaviorSubject([]) as BehaviorSubject<T>;
        privateListField.set(privateList);
        publicListField.set(privateList.asObservable());
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-18
      • 1970-01-01
      • 2017-02-23
      • 2020-07-26
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-02
      • 1970-01-01
      相关资源
      最近更新 更多