使用按钮后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>×</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()创建新的模态框实例,之前的模态框并未被销毁,而是叠加在页面上:
- 点击关闭按钮仅关闭最上层模态框,下层模态框的按钮暴露出来,造成“按钮高亮”的视觉效果;
- 点击外部关闭的次数等于叠加的模态框数量,因此次数与之前的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
相关产品推荐
相关产品推荐

