首页 > 解决方案 > 如何查看表单的 valueChanges 并获取表单控件名称?

问题描述

我有一种方法可以根据选择的值过滤数组,并通过与表单控件同名的属性对其进行过滤。

filterLum(val: string | number, c: AbstractControl | string): void {
     const formGroup = c.parent.controls;
     const name = Object.keys(formGroup).find((name) => c === formGroup[name]) || null;
     return this.data.filter(x => x[name] === val);
  }

为此,我在每个可以制作过滤器的表单控件中都有一个 valueChanges。像这样

this.valueWatcherSubscription = this.form
      .get('status')
      .valueChanges.pipe(takeUntil(this.unsubscribeSignal.asObservable()))
      .subscribe((val) =>
        val ? this.filterLum(val, this.form.get('status')) : null
      );

问题是我有超过 15 个表单控件,并且每个控件都有一个观察者。所以我为所有与数组交互的 formControls 做了一个观察者。像这样:

const exclude: string[] = ['default'];
    const keys = [];
    Object.keys(this.form.controls).forEach(key => {
      if (exclude.findIndex(q => q === key) === -1) {
        keys.push(this.form.get(key).valueChanges);
      }
    });
    const valueWatcherSubscription = merge(...keys);
    valueWatcherSubscription.subscribe((val) => console.log(val));

但是这里val只获取选择的值,但我还需要它来自哪里的表单的名称,有没有办法也可以取form.get('form.control')?这样我就可以在每个控件中使用 filterLum 函数了吗?

标签: angular

解决方案


有几种方法可以做到这一点。保持你所拥有的,最小的变化是让你的 observables 返回一个包含两个信息(namevalue)的对象,而不是仅仅返回 valueChanges 提供的值:

    const exclude: string[] = ['default'];
    const keys = [];
    Object.keys(this.form.controls).forEach(key => {
      if (exclude.findIndex(q => q === key) === -1) {
        keys.push(this.form.get(key).valueChanges.pipe(
          map(val => ({name: key, value: val})) // <------
        ));
      }
    });
    const valueWatcherSubscription = merge(...keys);
    valueWatcherSubscription.subscribe((val) => console.log(val));

您可以使用将字段数组转换为可观察对象数组,而不是使用单独的数组 ( keys)来填充它。forEachmap

此外, usingObject.entries()提供了属性和值,在您的情况下为nameformControl,因此您可以使用它而不是在逻辑()中查找表单控件this.form.get(key)

    const exclude: string[] = ['default'];

    const controlWatchers = Object.entries(this.form.controls)
      .filter(([key]) => !exclude.includes(key))
      .map(([name, control]) => control.valueChanges.pipe(
         map(value => ({ name, value }))
      ));
    );
    const formWatcher$ = merge(...controlWatchers);
    formWatcher$.subscribe(console.log);

最后一种方法是使用以下方法生成一个 observable from()

    const exclude: string[] = ['default'];

    const formWatcher$ = from(Object.entries(this.form.controls)).pipe(
      filter(([key]) => !exclude.includes(key))
      mergeMap(([name, control]) => control.valueChanges.pipe(
         map(value => ({ name, value }))
      ));
    );
    formWatcher$.subscribe(console.log);

推荐阅读