繁体   English   中英

Angular 更新sessionStorage后不写入值

[英]Angular doesn't write the value after updating sessionStorage

我的代码非常简单,我的组件中有这个 html

<h2>{{username}}</h2>
<h2>{{sessionId}}</h2>

这是我用来更新这些变量的脚本


    //i check for when the router redirects to the /user component
    router.events.pipe(
      filter((e: Event): e is RouterEvent => e instanceof RouterEvent)
    ).subscribe(() => {
      //router event happens
      if (location.path() == "/user") {
        //I do a call to the backend to get the user info I need
        let userTemp = <string>sessionStorage.getItem("username");
        const params = new HttpParams()
          .set('username', userTemp);
        //the call happens in the service calss that I inject
        this.service.getUserInfo(params);
        //all it does is getting the data and sessionStorage.setItem() on both values
        this.username = <string>sessionStorage.getItem("username");
        this.sessionId = <string>sessionStorage.getItem("sessionId");
      }
    });

即使我先设置值然后获取它们,html 中也只显示了用户名变量, <h2></h2>标签之间没有绘制 sessionId 变量。 这可能是因为我在 sessionStorage 中已经有了“用户名”值。 注意:两个变量在 class 中都设置为“null”

这是服务:

getUserInfo(params: HttpParams) {
    this.http.get<UserData>('/api/getuserinfo', { params, responseType: 'json' }).subscribe(response => {
      //I set the username again
      sessionStorage.setItem("username", response.username);
      //I add a new value called sessionId
      sessionStorage.setItem("sessionId", response.sessionId);
    });
  }

我尝试设置 ngOnInit() function 以设置初始化值,然后在服务调用后调用 this.ngOnInit() 但即使 function 被调用。 代码上的任何变化都没有帮助,而且我没有找到任何可以解释为什么 Angular 看不到变量更新的内容,即使从调试器我可以访问 sessionStorage object 中的值。

你拥有的是因为每个 function 被 Javascript 引擎执行的时间。

查看您的代码,您有一个可观察的“router.events”,它在其订阅中执行几项操作。 直到这里一切都很好。 然而,问题发生在订阅内,更准确地说,是在执行对您的服务的调用时。

subscribe(() => {
  if (location.path() == "/user") {
    let userTemp = <string>sessionStorage.getItem("username");
    const params = new HttpParams().set('username', userTemp);
    
    this.service.getUserInfo(params); // <- Here is the issue.
    
    this.username = <string>sessionStorage.getItem("username");
    this.sessionId = <string>sessionStorage.getItem("sessionId");
  }
})

javascript执行这段代码时,顺序如下:

  1. 进入if块;
  2. 尝试从sessionStorage获取"username"并将其分配给userTemp
  3. 创建params HttpParams 实例并设置提供的属性的值。
  4. 调用getUserInfo(params) 此方法创建并可观察并订阅它。
  5. 尝试从sessionStorage获取"username"并将其分配给this.username
  6. 尝试从sessionStorage获取"sessionId"并将其分配给sessionId
  7. 解析getUserInfo(params) subscribe中的代码,它在sessionStorage中设置值。

如您所见,问题在于您希望第 7 步在第 5 步和第 6 步之前执行。

为此,您要么需要依赖可观察运算符(这更复杂),要么需要将this.service.getUserInfo(params)的返回值转换为Promise并等待其解析。

如果要将其转换为Promise ,最简单的方法如下:

getUserInfo(params: HttpParams): Promise<void> {
  this.http.get<UserData>('/api/getuserinfo', { params, responseType: 'json' })
    .pipe(tap(response => {
      sessionStorage.setItem("username", response.username);
      sessionStorage.setItem("sessionId", response.sessionId);
    })).toPromise();
}

在您的订阅中,您还需要将其修改为异步,如下所示:

subscribe(async () => {  // Add async here
  if (location.path() == "/user") {
    let userTemp = <string>sessionStorage.getItem("username");
    const params = new HttpParams().set('username', userTemp);
    
    await this.service.getUserInfo(params); // Await the resolution of the api call
    
    this.username = <string>sessionStorage.getItem("username");
    this.sessionId = <string>sessionStorage.getItem("sessionId");
  }
})

问题是您甚至在设置之前就获得了 session 个密钥。 实际上,当你在 stream 上订阅时,代码不会停止跟踪,直到响应到来。 订阅后的所有行立即运行。 如果你想从 session 获取数据,你应该把代码放在订阅中。 所以你应该完全按照Giovanni Grana在他的回答中所说的去做。

这是我在不使用 promise 的情况下解决它的方法。我在服务中返回 http.get,如下所示:

getUserInfo(params: HttpParams) {
return this.http.get<UserData>('/api/getuserinfo', { params, responseType: 'json' })
  .pipe(tap(response => {
    sessionStorage.setItem("username", response.username);
    sessionStorage.setItem("sessionId", response.sessionId);
  }));
}

并在我使用该服务的组件中订阅 service.getUserInfo(params):

this.service.getUserInfo(params).subscribe(() => {
      this.update();
    });

update 是一个 function ,它只更新变量:

update() {
    this.username = <string>sessionStorage.getItem("username");
    this.sessionId = <string>sessionStorage.getItem("sessionId");
}

通过这样做,我强制更新在获取完成后发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM