Angular 订阅的变量不显示

Angular subscribed variable not displaying

我正在编写一些用户管理代码。基本上,单击一个按钮,我希望它保存一个新用户,然后显示我保存在商店中的输入密码。我的代码看起来有点像这样:

onClick() {
/*Insert filling up the newUser variable from the form here*/
this.store.dispatch(new AddUser(this.newUser)) 
    this.store.select(userFeature.getPassword).subscribe(
      pass => {
      this.temp = pass; //I've tried using this.password here, but also nothing
    })
    setTimeout(() => {
      this.pause();
    }, 5000);
    //this.password = "Stuff" <-- This DOES work
    this.password = temp //This executes despite the wait above
}

pause(){
    if(this.temp === null){
        setTimeout(() => {
          this.pause();
        }, 500);
        console.log("Waiting...")
      }
}

在我的 HTML 中,我在一个简单的范围内使用 {{password}}。

编辑:已修复!我需要使用 ChangeDetectorRef。

this.store.dispatch(new AddUser(this.newUser))
    this.store.select(userFeature.getPassword).subscribe(
      pass => {
      this.password = pass;
      this.cd.detectChanges();
      });

我加了一个ChangeDetectorRef,赋值后调用通过

    this.store.select(userFeature.getPassword).subscribe(
      pass => {
      this.password = pass;
      this.cd.detectChanges();
      });

你的代码片段中有很多地方做错了,首先要澄清的是同步和异步执行。

一段代码通常是从上到下逐行执行,这就是我们所说的“同步执行”示例:

// Start of block 

let variable = 1; // Here variable is going to have a value of 1
variable = variable + 1; // Here variable is going to have a value of 2

// End of block

现在让我们看一下异步执行,在示例中说明它的最佳方式是使用 setTimout,但请记住,有许多异步操作,例如调用后端端点,或使用 Promise / Observable

// Start of block 1

let variable = 1; // Here variable is going to have a value of 1

setTimeout(() => {
   // Start of block 2

   variable = variable + 1; // Here variable is going to have a value of 3
   variable = variable + 1; // Here variable is going to have a value of 4

   // End of block 2
}, 1000);

variable = variable + 1; // Here variable is going to have a value of 2

// End of block 1

所以在此示例中,“块 1”的执行是同步的,“块 2”的执行是同步的,但是块 2 稍后执行(在本示例中为 1 秒后)。并不是说Block 1要等1秒再执行Block 2再继续执行Block 1,这叫non-blocking,每个Block都会不间断地执行,它们可能同时执行,也可能不同时执行,在很多情况下,没有办法真正控制它。

NgRx

既然我们解释了 non-blocking 和异步,让我们来谈谈 NgRx。

// Start of block

store.dispatch(...)
store.select(...)

// End of block

Dispatch 和 Select 将一个接一个地执行,并且每个都有一些将要触发的异步代码。这意味着您无法保证 Dispatch 的异步代码将在 Select 的异步代码之前执行,这导致您的 passwordundefined 因为你在设置之前读取它,现在最终它会被设置但不是同步的。

在你的例子中,你可以快速修复它,只需将你的逻辑包装在检查密码是否设置成这样

this.store.select(userFeature.getPassword).subscribe(
  pass => {
   if(pass) {
     this.temp = pass;
     /* Do Something with your pass */
   }
  }
)

// OR 

this.store.select(userFeature.getPassword).pipe(
  filter((pass) => !!pass),
  tap((pass) => {
    this.temp = pass;
     /* Do Something with your pass */
  }),
).subscribe()

在其他情况下,它可能比这更复杂,因为您需要在 Action 和 State 中使用一些同步令牌来确保您正在读取与正确的 action side effect 对应的值。

你不应该为此使用 this.cd.detectChanges();

注意

我刚刚解决了这个片段,但我没有看到像你的例子这样的东西的功能要求是什么,你可能想重新考虑你的逻辑。另外,不要忘记取消订阅您的 select,这很重要。