Angular 2-更新隐藏的表单字段,然后张贴到外部页面



我有一个Angular2应用程序,它在某个时候需要通过POST请求将用户发送到外部服务上的页面。

基本上,流程应如下

  • 用户点击按钮
  • 拦截并阻止默认表单提交事件
  • 执行API调用是为了在后台设置一些内容并检索一些值以传递给外部服务
  • 一些隐藏的表单字段填充有从API检索到的数据
  • 表单提交随后被解雇

据我所知,在Angular中没有办法执行"POST到外部页面"类型的操作,必须用ngNoForm覆盖Angular的表单处理,并允许浏览器将其作为常规POST处理。

所以,目前,我有一个这样的模板:

<form ngNoForm (submit)="proceedToService($event)" method="POST" action="https://some-service.com/etc">
<input type="hidden" name="token" [value]="someToken">
<button type="submit">Proceed to external service</button>
</form>

在组件中,我有这样的:

public someToken:string="";
proceedToService($event) {
$event.preventDefault();
this.apiHandler.doSomeStuff().subscribe(
(someStuff) => {
this.someToken = someStuff.token;
$event.target.submit();
}
);
}

(doSomeStuff返回Observable)

这种方法的问题是,提交事件似乎在DOM中填充值之前就被触发了,这意味着POST请求中的token字段是空的。

我能够通过将$event.target.submit();封装在setTimeout调用中使其工作,如下所示:

setTimeout(() => {$event.target.submit()}, 1000);

但这感觉像是一种超级黑客的方法,无论如何都可能失败(如果更新需要1秒以上怎么办?)而且很难测试。

那么,有没有更好的方法来实现这一点呢?理想情况下,我想做的是观察隐藏输入的值在DOM中的实际更新,然后在那时触发提交。但到目前为止,我还无法找到实现这一点的方法——例如,ngModel绑定不支持隐藏字段。

我对Angular世界非常陌生,尤其是Angular2,所以我可能从完全错误的角度来处理这个问题,但任何帮助都将不胜感激。

您可以通过使用模板引用变量和button type="button"组合来实现这一点。

<form ngNoForm #extForm method="POST" action="https://some-service.com/etc">  
<button type="button" (click)="proceedToService(extForm)">External Service</button>
</form>

打字稿功能

proceedToService(frm) {
this.apiHandler.doSomeStuff().subscribe(
(someStuff) => {        
var input = document.createElement("input");
input.type = "hidden";
input.name = "token";
input.value = someStuff.token;;
frm.appendChild(input);
frm.submit();
}
);
}

我希望这能帮助你

我使用AfterViewChecked找到了一个潜在的解决方案,如下所示:

private pendingEvent;
proceedToService($event) {
$event.preventDefault();
this.apiHandler.doSomeStuff().subscribe(
(someStuff) => {
this.someToken = someStuff.token;
this.pendingEvent = $event;
}
);
}
ngAfterViewChecked() {
if ( this.pendingEvent ) {
this.pendingEvent.target.submit();
this.pendingEvent = null;
}
}

这似乎符合我的要求——因为ngAfterViewChecked是在检查视图后调用的,视图是在更新后检查的(我认为是?),所以此时值填充正确。

同样,在我对Angular不熟悉的情况下,我不确定这是否是最佳解决方案,甚至是实践中可行的解决方案,但它至少比使用setTimeout"感觉"更好。。。

相关内容

最新更新