【问题标题】:Problem loading async data into a form and then submitting it将异步数据加载到表单然后提交时出现问题
【发布时间】:2019-03-17 18:48:33
【问题描述】:

我的应用程序中有一个名为 redirectComponent 的组件,它只是通过调用放置它的路由 (http://localhost:4200/redirect/) 从应用程序的其他组件调用和实例化。

一旦调用 redirectComponent ,它会调用 2 次 API 以加载绑定到模板中表单的一些数据,一旦加载数据,我通过 ViewChild 访问表单并提交它(POST 方法),然后是这个组件完成了,我导航回根 url:不幸的是,即使来自 API 的数据被解析,表单的绑定数据也没有得到更新,并且它使用未定义的值提交。

TYPESCRIPT sn-p:

export class RedirectComponent implements AfterViewInit {
  userName: string;
  sessionToken: string;
  sessionDuration: string;
  loggedUserNavigationUrl: string = 'someUrl.com';

  @ViewChild('microgameform')
  microgameForm: ElementRef;

  constructor(private thirdPartyGameService: ThirdPartyGameService) { }

  async ngAfterViewInit(): Promise<void> {
    await this.redirectUserToThirdPartyGame();
  }

  async redirectToThirdParty(): Promise<void> {
    this.sessionDuration = '51';

    const gameToken: GameToken = await this.thirdPartyGameService.getGameToken();
    this.sessionToken = gameToken.Token;

    const nickNameResponse: NickName = await this.thirdPartyGameService.getNickname();
    this.userName = nickNameResponse.NickName;

    this.microgameForm.nativeElement.submit();
    this.router.navigateByUrl('/');
  }
}

HTML sn-p:

<form #microgameform name="MicrogameForm" [action]="loggedUserNavigationUrl" method="POST" target="_blank">
    <input type="hidden" name="Username" [value]="userName"/>
    <input type="hidden" name="SessionToken" [value]="sessionToken"/>
    <input type="hidden" name="SessionDuration" [value]="sessionDuration"/>
</form>

现在,当我使用 console.log() 查看 this.microgameForm.nativeElement.submit(); 之前的每个变量时,我发现所有变量都已加载但未绑定到表单,这是我得到的结果:

variables and form values before submit

我想我遗漏了一些东西,我需要从 API 中检索数据,然后使用 post 方法将其提交到表单。可能我遇到了一些竞争条件问题,但我无法弄清楚,我尝试从不同的生命周期钩子(例如:ngAfterViewInit)调用重定向,但我得到不同的错误......

【问题讨论】:

    标签: angular typescript data-binding async-await


    【解决方案1】:

    问题与这些行之间的某些并发有关:

    this.microgameForm.nativeElement.submit(); this.router.navigateByUrl('/');

    navigationByUrl 出于某种未知原因从表单中删除了值,或者更糟糕的是从 html 文档中删除了表单,因此解决方案是从 typescript 代码将 html 表单添加到文档中并从那里提交表单。

    【讨论】:

      【解决方案2】:

      确实,您需要使用.subscribe() 进行异步调用:

      this.thirdPartyGameService.getNickname().subscribe( data => {
          this.sessionToken = data.Token;
      });
      

      如果您尝试在订阅之外记录 this.sessionToken ,它将是未定义的:

      this.thirdPartyGameService.getNickname().subscribe( data => {
          this.sessionToken = data.Token;
          // Operations with the Token
      });
      // this.sessionToken not loaded yet => undefined
      

      【讨论】:

      猜你喜欢
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 1970-01-01
      • 2019-12-10
      相关资源
      最近更新 更多