Angular 角度变量不显示

Angular 角度变量不显示,angular,typescript,ngrx-store,Angular,Typescript,Ngrx Store,我正在编写一些用户管理代码。基本上,只要点击一个按钮,我希望它保存一个新用户,然后显示我正在商店中保存的输入密码。我的代码看起来有点像这样: onClick() { /*Insert filling up the newUser variable from the form here*/ this.store.dispatch(new AddUser(this.newUser)) this.store.select(userFeature.getPassword).subscribe(

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

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...")
      }
}

我添加了一个ChangeDetectorRef,并在分配给pass后调用它

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

我添加了一个ChangeDetectorRef,并在分配给pass后调用它

    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秒之后)。这并不意味着块1将等待1秒,然后执行块2并继续执行块1。它被称为非阻塞,每个块都将不间断地执行,它们可能会也可能不会同时执行,在许多情况下,没有办法真正控制它

NgRx

现在我们已经解释了非阻塞和异步,让我们来谈谈NgRx

// Start of block

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

// End of block
Dispatch和Select将一个接一个地执行,每一个都会触发一些异步代码。这意味着您不能保证在Select的异步代码之前执行调度的异步代码,这会导致您的密码未定义因为您在设置它之前读取它,现在它最终会被设置,但不会同步

在您的示例中,如果密码是这样设置的,只需将逻辑包装在检查周围,就可以快速修复它

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()
在其他情况下,它可能比这更复杂,因为您需要在操作和状态中使用一些同步令牌,以确保您正在读取与正确的操作副作用对应的值

您不应该使用
this.cd.detectChanges()用于此

注意


我刚刚提到了这个片段,但我不知道像您的示例这样的东西的功能需求是什么,您可能需要重新思考您的逻辑。另外,不要忘记取消订阅select,这一点很重要。

您的代码片段中有多处错误,首先要澄清的是同步和异步执行

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

// 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秒之后)。这并不意味着块1将等待1秒,然后执行块2并继续执行块1。它被称为非阻塞,每个块都将不间断地执行,它们可能会也可能不会同时执行,在许多情况下,没有办法真正控制它

NgRx

现在我们已经解释了非阻塞和异步,让我们来谈谈NgRx

// Start of block

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

// End of block
Dispatch和Select将一个接一个地执行,每一个都会触发一些异步代码。这意味着您不能保证在Select的异步代码之前执行调度的异步代码,这会导致您的密码未定义因为您在设置它之前读取它,现在它最终会被设置,但不会同步

在您的示例中,如果密码是这样设置的,只需将逻辑包装在检查周围,就可以快速修复它

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()
在其他情况下,它可能比这更复杂,因为您需要在操作和状态中使用一些同步令牌,以确保您正在读取与正确的操作副作用对应的值

您不应该使用
this.cd.detectChanges()用于此

注意


我刚刚提到了这个片段,但我不知道像您的示例这样的东西的功能需求是什么,您可能需要重新思考您的逻辑。另外,别忘了取消订阅您的select,这一点很重要。

您能与我分享更多信息吗?什么是userFeature.getPassword?以及store.select.the store.select和dispatch的功能内容是NGRX/store功能的一部分。在多个文档的多个页面上发布太多了。Dispatch发送AddUser API调用。Select是一个基本选择器,用于将变量密码从存储区中取出。不过,API需要时间,代码只是一直在运行,而不是等待。我想您需要这个。密码=这个。存储。在onClick()和{{password | async}之外选择(…).subscribe()。您能分享更多信息吗?什么是userFeature.getPassword?以及store.select.the store.select和dispatch的功能内容是NGRX/store功能的一部分。在多个文档的多个页面上发布太多了。Dispatch发送AddUser API调用。Select是一个基本选择器,用于将变量密码从存储区中取出。但是,API需要时间,代码只是一直在运行而不是等待。我认为您需要这个。password=this.store.select(…).subscribe()