Angular 5中锚点点击提交表单首次仅刷新页面的问题排查
解决Angular 5中首次点击锚点无法打开新标签页的问题
看起来你遇到的问题主要来自两个方面:a标签的默认行为干扰和Angular数据绑定的变更检测时机。下面是具体的分析和解决方案:
问题根源
- a标签默认行为未阻止:你的
<a>标签带有href="#",点击时会触发浏览器的默认锚点跳转行为(滚动到页面顶部),这会和表单提交的操作冲突,导致首次点击时浏览器优先处理跳转,表单提交被干扰,看起来像是刷新页面。 - ngModel绑定的DOM更新延迟:在
gotoApp1()的subscribe回调中,你修改了keyField和timeOutField,但Angular的变更检测需要时间将这些值同步到DOM的input元素上。如果在变更检测完成前就调用myform.submit(),此时input的value还是旧值(或空),导致表单提交无效;第二次点击时,这些值已经同步到DOM,所以能正常提交。
解决方案
步骤1:阻止a标签的默认行为
修改导航栏的a标签,在click事件中添加$event.preventDefault(),阻止默认的锚点跳转:
<a class="nav-item" href="#" (click)="gotoApp1(); $event.preventDefault()"> <img class="icon" src="images/app1.svg"> <span>App-1</span> </a>
步骤2:确保DOM更新后再提交表单
有两种方式可以确保ngModel绑定的值同步到DOM后再提交表单:
方式一:使用ChangeDetectorRef手动触发变更检测
先注入ChangeDetectorRef,然后在修改字段后手动检测变更,再提交表单:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core'; export class MajorComponent implements OnInit { private keyField:string; private timeoutInterval = 2000; // seconds constructor(private _service: YourService, private cdr: ChangeDetectorRef) {} // 注入ChangeDetectorRef ngOnInit() { // 现有代码 } gotoApp1() { this._service.getApp1Key().subscribe(key => { const myform = document.getElementById('app1') as HTMLFormElement; myform.action = key.app1Link; this.keyField = key.accessKey; this.timeOutField = this.timeoutInterval.toString(); // 手动触发变更检测,确保DOM更新 this.cdr.detectChanges(); myform.submit(); }); } }
方式二:直接操作input元素的value(绕过ngModel,更直接)
如果你不想依赖Angular的绑定,可以直接获取input元素并设置其value,这样能确保提交时值是最新的:
gotoApp1() { this._service.getApp1Key().subscribe(key => { const myform = document.getElementById('app1') as HTMLFormElement; myform.action = key.app1Link; // 直接设置input的value (document.getElementById('key') as HTMLInputElement).value = key.accessKey; (document.getElementById('timeOut') as HTMLInputElement).value = this.timeoutInterval.toString(); myform.submit(); }); }
这种方式不需要依赖ngModel,避免了变更检测的时机问题,代码更直接。
额外优化:隐藏表单的正确方式
注意你的表单里写的是stype.display="none",这里有拼写错误,应该是style.display="none",修正后才能正确隐藏表单:
<form id="app1" method="post" style.display="none" target="_blank">
验证效果
完成以上修改后,首次点击"App-1"锚点时,会直接触发表单提交,在新标签页打开目标应用,不会出现刷新页面的问题,控制台也不会有报错。
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

