我在此链接上发布了一个类似的问题:enter link description here,但是没有收到任何答案(我以为我有答案,但是现在我不太确定),并且仍然很困惑,所以我非常感谢反馈和指导。
我有一个反应式表单,在该表单中,当可观察对象发出数据(并调用订阅函数)时,以下订阅中的函数将评估itm["value"].length-1
。
this.formCtls[controlName] = new FormControl('', {updateOn: 'blur'});
this.userForm.addControl(controlName, this.formCtls[controlName]);
this.formCtls[controlName].valueChanges.subscribe(val=>{
itm["value"][itm["value"].length-1]=val;
this.renderDataArray();
});
但是,我希望在可观察的(FormControl)为
itm["value"].length-1
时对订阅回调函数表达式created
进行求值。例如,在创建表单控件时,
itm["value"].length
可能仅为2,但是在Observable发出数据时,itm["value"].length
可能是6或7或任何其他数字。我如何(以编程方式)确保将值“ 2”(或等效值)输入到订阅回调中,而不是“ 6”或“ 7”,或者观察到的Observable发出的值是什么?我想到了两种方法,但不确定哪种方法有效:
首先声明
const itmLength = itm["value"].length
,然后构造回调,即:const itmLength = itm["value"].length;
this.formCtls[controlName] = new FormControl('', {updateOn: 'blur'});
this.userForm.addControl(controlName, this.formCtls[controlName]);
this.formCtls[controlName].valueChanges.subscribe(val=>{
itm["value"][itmLength-1]=val;
this.renderDataArray();
});
但是我不确定
itmLength
是否包含实际值(在这种情况下上述方法可行),或者是指向itm["value"].length
的指针(在上述情况下上述方法无效)。我以为这种方法可以正常工作,但是后来我更改了代码,遇到了“块作用域变量”问题,解决此问题的唯一方法是在内部循环外部声明const / variable,然后执行以下操作:代码停止给我期望的“ 2”,并继续给我不希望的“ 6”或“ 7”。因此,通常来说,第一种方法有效吗? (或者const itmLength
只是一个指针,在这种情况下itm["value"].length
仅在Observable发出时才被评估)?第二种方法是将
pipe
添加到可观察对象中,例如:this.formCtls[controlName].valueChanges.pipe(
switchMap(v=>Object.assign({},{value: v}, {length: itm["value"].length}))
.subscribe(val=>{
itm["value"][val.length-1]=val.value;
this.renderDataArray();
});
我不确定第二种方法是否有任何好处,或者不确定是否仅在发出
itm["value"].length
Observable时而不是在创建formControl回调时才评估valueChanges
。如果有人有任何解决方案,或者可以对我这个问题提供一些见解,请在此先感谢。
=====
这是基于@Fan Cheung的出色解决方案的最终答案(说明
resultsSelector
的贬值):
of(itm["value"].length).
pipe(switchMap(length=>this.formCtls[ctlName].valueChanges.
pipe(map(newVal => [newVal,length]))
)).
subscribe(([newVal,length])=> . . .
最佳答案
您可以在流中组成itm["value"]
.length,它是整数而不是指针,因此在创建时是固定的。 of
运算符只会发出一次,然后切换到valueChanges
流
of(itm["value"].length)
.pipe(switchmap(length=>this.formCtls[controlName].valueChanges,
// result seletor
value=>[length,value]))
.subscribe(([length,value])=>{
....... do you stuff
});