如何在创建观察者时而不是在发出值时强制在观察者中评估表达式

时间:2019-10-13 04:59:17

标签: javascript angular rxjs

我在此链接上发布了一个类似的问题: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();
  });

但是,我希望在observable /(FormControl)为itm["value"].length-1时对订阅回调函数表达式created进行评估。

例如,在创建表单控件时,itm["value"].length可能仅为2,但是在Observable发出数据时,itm["value"].length可能是6或7或任何其他数字。我如何(以编程方式)确保将值“ 2”(或其等效值)输入到订阅回调中,而不是“ 6”或“ 7”,或者在Observable发出时的值是什么?

我想到了两种方法,但不确定哪种方法有效:

  1. 首先声明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。 / p>

如果有人有任何解决方案或可以对我解决这个问题提供一些见解,请多谢。

=====

这是基于@Fan Cheung提供的出色解决方案的最终答案(说明resultsSelector被弃用)


of(itm["value"].length).
   pipe(switchMap(length=>this.formCtls[ctlName].valueChanges.
      pipe(map(newVal => [newVal,length]))
      )).
   subscribe(([newVal,length])=> . . .

1 个答案:

答案 0 :(得分:1)

您可以在流中组成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
      });