angular - 如何查看表单的 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 函数了吗?
解决方案
有几种方法可以做到这一点。保持你所拥有的,最小的变化是让你的 observables 返回一个包含两个信息(name
和value
)的对象,而不是仅仅返回 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
)来填充它。forEach
map
此外, usingObject.entries()
提供了属性和值,在您的情况下为name
和formControl
,因此您可以使用它而不是在逻辑()中查找表单控件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);
推荐阅读
- javascript - 如何对多个选择字段值求和,包括减去负数(为零)
- regex - 使用 Tableau 提取段落中的多个单词的正则表达式
- c# - CultureInfo nb-NO DateTime.TryParse 在 VS2019 和 dotnetfiddle.net 上的差异
- matlab - 如何解释优化的相对停止容差?
- git - 拉着嫁接的树枝?
- regex - 是否可以连续比较两个值并获取所需的值,但两个值都与写入的正则表达式匹配
- c# - 有没有办法使用更多线程运行单个方法调用?
- javascript - 如何仅使用一个捕获来处理尝试中的错误?
- javascript - 使用 options.items 与标题的 JQuery UI 工具提示扩展
- file - 如何在 Crystal 中读取文件?