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

使用按钮后Angular Modal无法正常隐藏的问题排查

Angular模态框关闭异常问题

模态框模板代码

<ng-template #AllNewsModal>
<div class="card start-news" id="START_NEWS_MODULE">
    <div class="card-header">
        <div class="card-title">
            <span>{{ "Start.News" | translate }} </span>
            <span class="badge badge-secondary ml-1" *ngIf="news_modal && news_modal.UnreadCnt > 0">{{ news_modal.UnreadCnt }}</span>
            <app-tip class="mr-1 pull-right" id="START_NEWS"></app-tip>
        </div>
    </div>
    <div class="modal-body pb-0" [ngStyle]="{ 'overflow-y': !ShowMessageMode_modal ? 'hidden' : 'auto' }" *ngIf="!ShowMessageMode_modal">
        <span class="font-set3">{{ "Start.NewsDescription" | translate }}</span>
        <button type="button" class="close" (click)="CloseModal()">
            <span>&times;</span>
        </button>
    </div>
    <div class="modal-body pb-0" *ngIf="ShowMessageMode_modal && news_sel_modal && news_sel_modal.Title">
        <span class="font-set3"> {{news_sel_modal.Title}}</span>
        <div class="text-success pull-right" *ngIf="news_sel_modal.PublicationDate">
            {{ news_sel_modal.PublicationDate | date: State.FmtDate }}
        </div>
        <div class="text-success pull-right" *ngIf="!news_sel_modal.PublicationDate">
            {{ news_sel_modal.Created | date: State.FmtDate }}
        </div>
    </div>
    <hr class="mb-0" />
    <div class="modal-body pt-0" style="max-height: 70vh;">
        <div *ngIf="!ShowMessageMode_modal && news_modal && news_modal.Pubs">
            <ul class="list-group list-group-flush">
                <li class="list-group-item clickable px-0" *ngFor="let i of news_modal.Pubs" (click)="ShowMessage(i, true)">
                    <div class="pull-right text-success">
                        <div *ngIf="i.PublicationDate" class="ml-2 mb-2">
                            <i class="fa fa-fw fa-dot-circle-o" *ngIf="!i.IsRead"></i>
                            {{ i.PublicationDate | date: State.FmtDate }}
                        </div>
                        <div *ngIf="!i.PublicationDate" class="ml-2 mb-2">
                            <i class="fa fa-fw fa-dot-circle-o" *ngIf="!i.IsRead"></i>
                            {{ i.Created | date: State.FmtDate }}
                        </div>
                    </div>
                    <div class="text-justify" [innerHtml]="i.Content.ShortHtml"></div>
                </li>
            </ul>
            <div class="modal-footer d-flex justify-content-between">
                <button type="button" (click)="ViewAllNews(true, false)" class="btn btn-outline px-0 color-light70-graphite" [ngStyle]="{'visibility': news_page > 0 ? 'visible' : 'hidden'}">
                    <i class="fa fa-fw fa-arrow-left"></i>
                    {{ "Button.Back" | translate }}
                </button>
                <button type="button" (click)="ViewAllNews(true)" class="btn btn-outline px-0 color-light70-graphite" [ngStyle]="{'visibility': !no_next ? 'visible' : 'hidden'}">
                    <i class="fa fa-fw fa-arrow-right"></i>
                    {{ "Button.Next" | translate }}
                </button>
            </div>
        </div>
        <div class="modal-body px-0 pb-0" *ngIf="ShowMessageMode_modal && news_sel_modal">
            <div class="text-justify" [innerHtml]="news_sel_modal.Content.ContentHtml"></div>
            <hr />
        </div>
    </div>
    <div class="modal-footer" *ngIf="ShowMessageMode_modal && news_sel_modal">
        <button type="button" (click)="HideMessage(true)" class="btn btn-outline px-0 color-light70-graphite">
            <i class="fa fa-fw fa-arrow-left"></i>
            {{ "Button.Back" | translate }}
        </button>
    </div>
</div>
</ng-template>

关闭函数代码

public CloseModal(){
 let t = this;
 t.modal_all_news.hide();
}

问题现象

  • 打开模态框后直接点击关闭按钮,模态框可正常隐藏;
  • 点击过Back或Next按钮后,再点击关闭按钮,最后点击的那个按钮会被高亮;
  • 点击模态框外部多次后,模态框会关闭,需要点击的次数与之前点击Back/Next的次数相关:比如点击1次Next后需点击外部3次,点击2次Next需点击5次。

模态框触发代码

<div class="card-header">
<div class="card-title">
    <span (click)="ViewAllNews(true, false, true)">{{ "Start.News" | translate }} </span>
    <span class="badge badge-secondary ml-1" *ngIf="news && news.UnreadCnt > 0">{{ news.UnreadCnt }}</span>
    <app-tip class="mr-1 pull-right" id="START_NEWS"></app-tip>
</div>
</div>

触发函数代码

public ViewAllNews(modal: boolean = false, forward: boolean = true, initial: boolean = false) {
    let t = this;
    let pageSize = 1;

    if(initial){
        t.news_page = 0;
        t.no_next = false;
    }

    if(modal){
        if(forward){
            t.news_page++;
        } else {
            if(t.news_page > 0){
                t.news_page--;
            }
        }
    }

    let req = <GetNewsReq>{
        AccountId: t.State.CurrentUser.Id,
        PageSize: modal ? pageSize + 1 : 3,
        SkipFirst: modal ? pageSize*t.news_page : 0
    };
    
    // get additional items
    t.State.StartWorking();
    t.http.post<GetNewsRes>(environment.BaseApiUrl + "api/Publication/GetNews", req).subscribe(res => {
        if (res) {
            t.news_modal = res;
            t.modal_all_news = t.modal_srv.show(t.modal_template_all_news, {
                class: "modal-dialog modal-dialog-scrollable modal-lg"
            });

            if(modal){
                if(forward){
                    if(res.Pubs.length <= pageSize) {
                        t.no_next = true;
                    } else {
                        res.Pubs.pop();
                    }
                } else {
                    t.no_next = false;
                    res.Pubs.pop();
                }
            }
            
        } else {
            // TODO: display error
        }
    });
    
}

问题原因

每次点击Back/Next按钮时,ViewAllNews函数都会在请求成功后调用modal_srv.show()创建新的模态框实例,之前的模态框并未被销毁,而是叠加在页面上:

  1. 点击关闭按钮仅关闭最上层模态框,下层模态框的按钮暴露出来,造成“按钮高亮”的视觉效果;
  2. 点击外部关闭的次数等于叠加的模态框数量,因此次数与之前的Back/Next点击次数相关。

解决方案

方案1:创建新模态框前关闭旧实例

修改ViewAllNews函数的请求成功回调部分,先关闭已存在的模态框再创建新实例:

if (res) {
    t.news_modal = res;
    // 先关闭已存在的模态框
    if(t.modal_all_news) {
        t.modal_all_news.hide();
    }
    t.modal_all_news = t.modal_srv.show(t.modal_template_all_news, {
        class: "modal-dialog modal-dialog-scrollable modal-lg"
    });

    // 原有逻辑
    if(modal){
        if(forward){
            if(res.Pubs.length <= pageSize) {
                t.no_next = true;
            } else {
                res.Pubs.pop();
            }
        } else {
            t.no_next = false;
            res.Pubs.pop();
        }
    }
}

方案2:仅初始化时创建模态框,后续仅更新数据

将模态框创建逻辑移到初始化分支,后续点击Back/Next仅更新数据,避免重复创建模态框:

public ViewAllNews(modal: boolean = false, forward: boolean = true, initial: boolean = false) {
    let t = this;
    let pageSize = 1;

    if(initial){
        t.news_page = 0;
        t.no_next = false;
        // 仅初始化时创建模态框
        t.modal_all_news = t.modal_srv.show(t.modal_template_all_news, {
            class: "modal-dialog modal-dialog-scrollable modal-lg"
        });
    }

    if(modal){
        if(forward){
            t.news_page++;
        } else {
            if(t.news_page > 0){
                t.news_page--;
            }
        }
    }

    let req = <GetNewsReq>{
        AccountId: t.State.CurrentUser.Id,
        PageSize: modal ? pageSize + 1 : 3,
        SkipFirst: modal ? pageSize*t.news_page : 0
    };
    
    t.State.StartWorking();
    t.http.post<GetNewsRes>(environment.BaseApiUrl + "api/Publication/GetNews", req).subscribe(res => {
        if (res) {
            t.news_modal = res;
            
            if(modal){
                if(forward){
                    if(res.Pubs.length <= pageSize) {
                        t.no_next = true;
                    } else {
                        res.Pubs.pop();
                    }
                } else {
                    t.no_next = false;
                    res.Pubs.pop();
                }
            }
            
        } else {
            // TODO: display error
        }
    });
    
}

内容的提问来源于stack exchange,提问作者Årtør

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:34:55