简体   繁体   English

使用多个引导模式(ngx-bootstrap 和 Angular)时遇到问题

[英]Trouble using multiple bootstrap modals (ngx-bootstrap and Angular)

I really have a problem using multiple bootstrap modals within Angular 4. Maybe you can help me out of this.我在 Angular 4 中使用多个引导模式确实有问题。也许你可以帮我解决这个问题。 The code is working fine with just one modal.该代码仅使用一种模态即可正常工作。 I am not be able to use the buttons/form of the first loaded modal.我无法使用第一个加载的模态的按钮/表单。 The second is working fine.第二个工作正常。 After opening and closing the second modal, also the first modal works... strange.打开和关闭第二个模态后,第一个模态也起作用了……很奇怪。 Is there something wrong?有什么问题吗?

 <!-- ADD MODAL--> <div bsModal #addModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myAddModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Add Dimension</h4> <button type="button" class="close" (click)="addModal.hide()" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="formGroupInput">TAG</label> <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input" aria-describedby="keyHelp" value="" disabled> <small id="keyHelp" class="form-text text-muted">Notice that this field is a surrogate key!</small> </div> <div class="form-group"> <label for="formGroupInput2">Name</label> <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input" value=""> </div> <div class="form-group"> <label for="formGroupInput3">Description</label> <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input" value=""> </div> </form> </div> <div class="modal-footer"> <button type="button" id="dfsdfsdfsdf" class="btn btn-secondary" (click)="addModal.hide()">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <!-- EDIT MODAL--> <div bsModal #editModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Edit {{currentItem?.NAME}}</h4> <button type="button" class="close" (click)="editModal.hide()" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="formGroupInput">TAG</label> <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input" aria-describedby="keyHelp" value="{{currentItem?.TAG}}" disabled> <small id="keyHelp" class="form-text text-muted">You'll need to delete this entry to change this key value!</small> </div> <div class="form-group"> <label for="formGroupInput2">Name</label> <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input" value="{{currentItem?.NAME}}"> </div> <div class="form-group"> <label for="formGroupInput3">Description</label> <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input" value="{{currentItem?.COMM}}"> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="editModal.hide()">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>

 import { Component, OnInit, ViewChild } from '@angular/core'; import { DataService } from "../data.service"; import { ModalDirective } from 'ngx-bootstrap/modal/modal.component'; @Component({ templateUrl: './dimensions.component.html', styleUrls: ['./dimensions.component.scss'] }) export class DimensionsComponent implements OnInit { @ViewChild('editModal') public editModal: ModalDirective; @ViewChild('addModal') public addModal: ModalDirective; currentItem; openModal(item: any) { this.currentItem = item; this.editModal.show(); } openAddModal() { this.addModal.show(); } //Attributes public currentVar; subscription; dimensionData; rows; constructor(private _dataService: DataService) { }

Thank you for your time guys!谢谢你们的时间!

Update: By switching the modal sequence inside the code the problem also occures but just in terms of the other modal.更新:通过在代码内切换模态序列,问题也会发生,但只是在其他模态方面。

bsModal 指令并不真正适合嵌套模态,请转换为 bsModal 服务的使用,请参见此处的示例: https ://valor-software.com/ngx-bootstrap/#/modals#service-nested

So after a few fixes, production use and testings I can say I have found a solution to a nested ngx-bootstrap modal problems.因此,经过一些修复、生产使用和测试后,我可以说我已经找到了嵌套 ngx-bootstrap 模态问题的解决方案。 I have written a service-wrapper for a BsModalService .我为BsModalService编写了一个服务包装器。

modalIndexing = {};
hasInited = false;

constructor(
    router: Router,
    private modalService: BsModalService,
) {
    router.events
        .pipe(filter((event: NavigationEvent) => (event instanceof NavigationStart)))
        .subscribe(() => this.terminateAll());
}

// Just a modal dude
resolveModal(component, position: 'center' | 'static' = 'center', initialState?: any): void {
    const config: ModalOptions = {
        class: modalClassDict[position] + ' ss-modal',
        initialState
    };

    // For nested launches, wait until previous hide to open new
    setTimeout(() => {
        this.modalService.show(component, config);
    }, initialState.hasTimeout ? 600 : 0);
}

// Modal dude that will return something 
// if you want to of cause, no pressure
resolveModalSub(component, position: 'center' | 'static' = 'center', initialState?: any): Observable<any> {
    const config: ModalOptions = {
        class: modalClassDict[position] + ' ss-modal',
        initialState
    };

    const bsModalRef = this.modalService.show(component, config);
    bsModalRef.content.onClose = new Subject<any>();

    const modalSub = bsModalRef.content.onClose.pipe(take(1));
    this.healthCheck(modalSub);

    return modalSub;
}

// This sneaky little bastard will return something if it hides!
resolveModalSubCheckHide(component, position: 'center' | 'static' = 'center', initialState?: any): Observable<any> {
    const config: ModalOptions = {
        class: modalClassDict[position] + ' ss-modal',
        initialState
    };

    const bsModalRef = this.modalService.show(component, config);
    bsModalRef.content.onClose = new Subject<any>();

    const modalSub = bsModalRef.content.onClose.pipe(take(1));
    this.healthCheck(modalSub, true);

    return modalSub;
}

// This thingy does some pseudo-indexing and cleans up the mess you left
private healthCheck(modalSub, needToCheckHide = false) {

    // The only property ngx-bootstrap modal service
    // is able to return is the number of openned modals
    // so we are heading out from it 
    const index = this.modalService.getModalsCount();

    this.modalIndexing[index] = {
        modalSub,
        needToCheckHide
    };

    // First modal initiates onHide sub 
    if (!this.hasInited) {
        this.hasInited = true;

        this.modalService.onHide
            .subscribe(() => {
                if (_.keys(this.modalIndexing).length) {
                    // This event emits after the modal is closed so its a +1
                    const indexedSub = this.modalIndexing[this.modalService.getModalsCount() + 1];

                    // Handeles the case when you need to know if modal was closed
                    if (indexedSub.needToCheckHide) {
                        indexedSub.modalSub.next(false);
                    }

                    // Completes sub of a value return and cleans itself from dictionary
                    if (indexedSub.modalSub) {
                        indexedSub.modalSub.complete();
                    }
                    delete this.modalIndexing[this.modalService.getModalsCount() + 1];
                }
            });
    }
}

// Termiantes all modal windows in user navigates via back / forward
private terminateAll() {
    _.keys(this.modalIndexing).forEach(index => this.modalService.hide(index));
}

Basic usage:基本用法:

const data = {
  // your initial data
};

this.dialogService.resolveModalSubCheckHide(YourModalComponentToDisplay, 'center', data)
  .subscribe((value) => {
      // processing
  });

Features:特点:

  • Return value handling as subject作为主题的返回值处理
  • Performance friendly性能友好
  • Doesn`t leave any uncompleted subjects不会留下任何未完成的科目
  • Can return a value if hidden如果隐藏,可以返回一个值
  • Handles unlimited nested levels处理无限的嵌套级别
  • Can be queued to launch modals可以排队启动模态
  • Auto close on manual navigation手动导航时自动关闭

Hope this helps somebody <3.希望这有助于某人<3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM