javascript - 在表单提交中,javascript Angular 如何获取按钮元素

我有一个网页上面有多个表单。 每个表单上都有许多按钮。 我想在按下按钮后,在按钮上实现加载spinner。 当我使用普通点击事件时,我可以通过按钮:

HTML


<button #cancelButton class="button-with-icon" type="button" *ngIf="hasCancel" mat-raised-button color="warn" [disabled]="isLoading" (click)="clickEvent(cancelButton)">


 <mat-spinner *ngIf="isLoading" style="display: inline-block;" diameter="24"></mat-spinner>


 Cancel


</button>



TS


clickEvent(button: MatButton) {


 console.log(button);


}



在这种情况下按钮元素通过,你可以访问它,以便向按钮添加一个加载类。

但是,如果您使用提交按钮尝试相同的操作,

HTML


<form (ngSubmit)="save(saveButton)">


 <button #saveButton class="button-with-icon" type="submit" *ngIf="hasSave" mat-raised-button color="primary" [disabled]="isLoading">


 <mat-spinner *ngIf="isLoading" style="display: inline-block;" diameter="24"></mat-spinner>


 Save


 </button>


</form>



TS


save(button: MatButton) {


 console.log(button);


}



在这种情况下按钮是 undefined,因为按钮上的*ngIf 将它从窗体的范围中阻止。

https://stackblitz.com/edit/angular-zh7jcw-mrqaok?file=app%2Fform-field-overview-example.html

我已经尝试将点击事件添加到保存按钮,但由于按钮在设置为加载后被禁用,因此它永远不会调用提交 。

我查看了提交事件,但是,无法看到任何链接回单击按钮的内容。

有什么建议?

时间:

模板解决方案:删除 ngSubmit 并添加 click 事件以提交按钮


<form> 


 <button #saveButton (click)="save(saveButton)".. .> 


 <mat-spinner.. .> </mat-spinner>


 Save


 </button>


</form>



更新:对于有大量按钮加载的系统,您也可以尝试这个 - 更改函数: isLoading 到对象 ... - 工作示例在这里


class FormFieldOverviewExample {



 hasCancel = true;


 hasSave = true;


 isLoading = {};



 saveEvent(event, buttonName) {


 console.log(buttonName);


 this.isLoading[buttonName]=true;


//...


 }



 clickEvent(event, buttonName) {


 console.log(buttonName);


 this.isLoading[buttonName]=true;


//...


 }


}
form {display:none}

<form> 


 <button (click)="clickEvent($event, 'cancelButton')" [disabled]="isLoading['cancelButton']" *ngIf="hasCancel".. .>


 <mat-spinner *ngIf="isLoading['cancelButton']".. .></mat-spinner>


 Cancel


 </button> 



 <br><br>



 <button (click)="saveEvent($event, 'saveButton')" [disabled]="isLoading['saveButton']" *ngIf="hasSave".. .>


 <mat-spinner *ngIf="isLoading['saveButton']".. .></mat-spinner>


 Save


 </button>


</form>

这是我的解决方法 https://stackblitz.com/edit/angular-zh7jcw-ythpdb

首先当通过 (ngSubmit)="save(saveButton)" 调用时提交按钮 saveButtonundefined 的原因是你通过 <button #saveButton.. .> 定义的引用 #saveButton 仅在元素的 button 范围内可见且可访问; 另一方面父 form 元素对它一无所知 。

假设你有类似这样的内容:


<button #saveButton>


 <span (click)="saveEvent($event, saveButton)">Save</span>


</button>



然后在 saveEvent 方法中,你可以访问 saveButton 引用,因为它对它的子( 元素 span ) 范围是可见的。

但是,我会建议以下解决方案: 在关注点分离和 Angular 方式处理方面更合适,即通过引入两个新成员 cancelActive 和 submitActive 你将能够更灵活地处理表单的不同状态

你可以在这里看到它的实际作用: https://stackblitz.com/edit/angular-zh7jcw-ythpdb


export class FormFieldOverviewExample {


 cancelActive = false;


 submitActive = false;



//this is for submit event


 saveEvent(event: Event) {


//additional logic can be added


//if(!this.cancelActive) return;



 this.submitActive = true;


 this.cancelActive = false;


 }



//this is for cancel event


 cancelEvent(event: Event) {


//additional logic can be added


//if(!this.submitActive) return;



 this.submitActive = true;


 this.cancelActive = false;


 }



}




<form (ngSubmit)="saveEvent($event)">


 <button class="button-with-icon" type="button" *ngIf="hasCancel" mat-raised-button color="warn" [disabled]="cancelActive" (click)="cancelEvent($event)">


 <mat-spinner *ngIf="cancelActive" class="spinner" diameter="15"></mat-spinner>


 Cancel


 </button>


 <br><br>


 <button class="button-with-icon" type="submit" *ngIf="hasSave" mat-raised-button color="primary" [disabled]="submitActive">


 <mat-spinner *ngIf="submitActive" class="spinner" diameter="15"></mat-spinner>


 Save


 </button>


</form>



这样你还可以拥有更多的playground,例如:


<button type="submit" [disabled]="submitActive || cancelActive">...</button>



你可以简单地禁用 submit 按钮而不显示它的加载动画,如果你想出于某种原因这样做 。

此外,假设表单中有一个 <input type="text"/> 元素。 用户切换到该元素( 通过点击或tab键) ,并在完成编辑后按下回车键,在这种情况下表单也由浏览器自动提交;所以这会使你现有的代码结构中的事情变得更加复杂 。

这实际上与提交函数无关,但所有这些都与 Angular 和结构指令有关。 在应用结构指令( ngFor, ngIf.. .) 时, Angular 所做的是创建 ng-template节点。 这意味着,在结构指令范围内定义的模板引用变量仅在节点中可用。

所以, 你在这里有:


<button #saveButton *ngIf="hasSave">


 Save


</button>



表示 saveButton 模板引用仅可用 表示为该按钮创建的 ng-template 因此在提交函数中不可用

我们这里有:


<button #cancelButton *ngIf="hasCancel" (click)="clickEvent(cancelButton)">


 Cancel


</button>



按钮上是否有click事件,因此 cancelButton 模板引用变量可用于该事件。

...