如何实现点击HTML Alert确定后自动关闭Modal弹窗
问题描述
我开发了一款简易Web应用,用户点击按钮后会弹出带文本输入框的模态弹窗,输入内容后点击弹窗内的「Add」按钮即可提交新条目到数据库。
操作后会弹出HTML原生提示框告知添加操作是否成功。
当前用户点击提示框的确定按钮后会停留在模态弹窗,需手动点击关闭按钮关闭弹窗后,UI才会更新表格展示最新条目。
期望实现的效果:用户点击HTML提示框的「OK」按钮后模态弹窗同步自动关闭,无需手动操作。
相关代码
add-edit-star-component.html
<div class="form-froup row"> <label class="col-sm-2 col-form-label">Star Name</label> <div class="col-sm-10"> <input type="text" class="form-control" [(ngModel)]="StarName" placeholder="Enter Star Name"> </div> </div> <button (click)="addStar()" *ngIf="star.StarID==0" class="btn btn-primary"> Add </button> <button (click)="updateStar()" *ngIf="star.StarID!=0" class="btn btn-primary"> Update </button>
Star 后端控制器代码
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using WebApplication2.Models; namespace WebApplication2.Controllers { public class StarController : ApiController { public HttpResponseMessage Get() { string query = @"SELECT StarID, StarName FROM dbo.Star"; DataTable table = new DataTable(); using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["PlanetaryAppDB"].ConnectionString)) using(var cmd = new SqlCommand(query, con)) using(var da = new SqlDataAdapter(cmd)) { cmd.CommandType = CommandType.Text; da.Fill(table); } return Request.CreateResponse(HttpStatusCode.OK, table); } public string Post(Star star) { try { string query = "INSERT into dbo.Star (StarName) VALUES (@StarName)"; DataTable table = new DataTable(); using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["PlanetaryAppDB"].ConnectionString)) using (var cmd = new SqlCommand(query, con)) using (var da = new SqlDataAdapter(cmd)) { cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@StarName", star.StarName); da.Fill(table); } return "Added Successfully!!"; } catch (Exception e) { return "Failed to Add: " + e.ToString(); } } public string Put(Star star) { try { string query = @"UPDATE dbo.Star SET StarName = @StarName WHERE StarID = @StarID"; DataTable table = new DataTable(); using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["PlanetaryAppDB"].ConnectionString)) using (var cmd = new SqlCommand(query, con)) using (var da = new SqlDataAdapter(cmd)) { cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@StarName", star.StarName); cmd.Parameters.AddWithValue("@StarID", star.StarID); da.Fill(table); } return "Updated Successfully!!"; } catch (Exception e) { return "Failed to Update: " + e.ToString(); } } public string Delete(int id) { try { string query = "DELETE from dbo.Star WHERE StarID = @StarID"; DataTable table = new DataTable(); using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["PlanetaryAppDB"].ConnectionString)) using (var cmd = new SqlCommand(query, con)) using (var da = new SqlDataAdapter(cmd)) { cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@StarID", id); da.Fill(table); } return "Deleted Successfully!!"; } catch (Exception e) { return "Failed to Delete: " + e.ToString(); } } } }
add-edit-star.component.ts 代码
import { Component, OnInit, Input } from '@angular/core'; import { SharedService } from 'src/app/shared.service'; @Component({ selector: 'app-add-edit-star', templateUrl: './add-edit-star.component.html', styleUrls: ['./add-edit-star.component.css'] }) export class AddEditStarComponent implements OnInit { constructor(private service:SharedService) { } @Input() star:any; StarID!: string; StarName!: string; ngOnInit(): void { this.StarID = this.star.StarID; this.StarName = this.star.StarName; } addStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.addStar(val).subscribe(res=>{ alert(res.toString()); }); } updateStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.updateStar(val).subscribe(res=>{ alert(res.toString()); }); } }
解决方案
你只需要修改add-edit-star.component.ts文件,再对应调整父组件的模态框控制逻辑即可,后端代码完全不需要改动。
原生alert是同步阻塞API,用户点击确认后才会执行后面的代码,刚好可以利用这个特性在alert后加关闭模态框的逻辑,分两种常见场景处理:
场景1:使用ng-bootstrap/ngx-bootstrap模态框组件
这是Angular项目最常用的模态框方案,直接注入模态框实例调用关闭方法即可:
- 先导入对应的模态框实例类:
// 用ng-bootstrap的话加这句 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; // 用ngx-bootstrap的话加这句 // import { BsModalRef } from 'ngx-bootstrap/modal';
- 修改构造函数注入实例:
// ng-bootstrap版本 constructor(private service:SharedService, public activeModal: NgbActiveModal) { } // ngx-bootstrap版本 // constructor(private service:SharedService, public bsModalRef: BsModalRef) { }
- 修改
addStar和updateStar方法,alert后调用关闭:
addStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.addStar(val).subscribe(res=>{ alert(res.toString()); // ng-bootstrap用这句 this.activeModal.close(); // ngx-bootstrap用这句 // this.bsModalRef.hide(); // 还可以在这里加刷新列表的回调,直接更新父组件的表格数据 }); } updateStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.updateStar(val).subscribe(res=>{ alert(res.toString()); this.activeModal.close(); // 同上替换成对应的关闭方法 }); }
场景2:自定义模态框,父组件控制显隐
如果你的模态框是自己写的,通过父组件传布尔值控制显隐,就用自定义事件通知父组件关闭:
- 导入Output和EventEmitter:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
- 组件内定义关闭事件:
@Output() closeModal = new EventEmitter<void>();
- 修改
addStar和updateStar方法,alert后触发事件:
addStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.addStar(val).subscribe(res=>{ alert(res.toString()); this.closeModal.emit(); }); } updateStar() { var val = {StarID:this.StarID, StarName:this.StarName}; this.service.updateStar(val).subscribe(res=>{ alert(res.toString()); this.closeModal.emit(); }); }
- 父组件调用子组件的地方绑定事件,触发后修改控制模态框显隐的变量为false即可:
<app-add-edit-star [star]="currentStar" (closeModal)="isShowModal = false; refreshStarList()" ></app-add-edit-star>
refreshStarList()是你父组件获取星球列表刷新表格的方法,加在这里就可以关闭弹窗的同时刷新数据,不用用户手动刷新。
内容的提问来源于stack exchange,提问作者Trevor
相关产品推荐
相关产品推荐

