You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击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项目最常用的模态框方案,直接注入模态框实例调用关闭方法即可:

  1. 先导入对应的模态框实例类:
// 用ng-bootstrap的话加这句
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
// 用ngx-bootstrap的话加这句
// import { BsModalRef } from 'ngx-bootstrap/modal';
  1. 修改构造函数注入实例:
// ng-bootstrap版本
constructor(private service:SharedService, public activeModal: NgbActiveModal) { }
// ngx-bootstrap版本
// constructor(private service:SharedService, public bsModalRef: BsModalRef) { }
  1. 修改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:自定义模态框,父组件控制显隐

如果你的模态框是自己写的,通过父组件传布尔值控制显隐,就用自定义事件通知父组件关闭:

  1. 导入Output和EventEmitter:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
  1. 组件内定义关闭事件:
@Output() closeModal = new EventEmitter<void>();
  1. 修改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();
  });
}
  1. 父组件调用子组件的地方绑定事件,触发后修改控制模态框显隐的变量为false即可:
<app-add-edit-star 
  [star]="currentStar" 
  (closeModal)="isShowModal = false; refreshStarList()"
></app-add-edit-star>

refreshStarList()是你父组件获取星球列表刷新表格的方法,加在这里就可以关闭弹窗的同时刷新数据,不用用户手动刷新。


内容的提问来源于stack exchange,提问作者Trevor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 12:09:03