Как закрыть несколько диалоговых окон, используя Angular - PullRequest
0 голосов
/ 16 апреля 2020

У меня запущено приложение Angular 9, и я создал собственное диалоговое окно. Я также использовал ComponentFactoryResolver для динамической загрузки компонента.

Мое настраиваемое диалоговое окно выглядит следующим образом:

enter image description here

Итак, когда я нажимаю на кнопке закрытия диалоговое окно закрывается.

В соответствии с текущей реализацией, если я открою несколько диалоговых окон на экране, то я смогу закрыть только последнее открытое диалоговое окно, нажав кнопку закрытия.

Мое ожидаемое поведение - закрыть все диалоговые окна. Пожалуйста, помогите мне в этом

Демонстрация Stackblitz: https://stackblitz.com/edit/dialog-box-overlay

Примечание: В этой демонстрации Stabblitz один модал открывается поверх другого модального, поскольку я не изменял css. Поэтому, пожалуйста, обратите внимание на модальное имя, чтобы узнать, какой модальный режим открыт

1 Ответ

1 голос
/ 16 апреля 2020

Вместо назначения созданного модального компонента свойству services dcRef вам нужно управлять всеми вашими модальными компонентами, то есть в списке. Метод open() вашей службы

open(component: Type<any>, modalName: string) {
    const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
    this.dcRef = factory.create(this.injector);
    ...
    return this.dcRef;
}

возвращает ссылку на компонент. Вы можете управлять этой ссылкой из вызывающей стороны и передавать ее в качестве аргумента в свой метод close(). Когда все ссылки на компоненты управляются службой, вы также можете «пакетно закрыть» все модалы (см. closeAll()):

@Injectable()
export class DialogService {

    refs: ComponentRef<DialogComponent>[] = [];

    constructor(private componentFactoryResolver: ComponentFactoryResolver,
        private applicationRef: ApplicationRef,
        private injector: Injector
    ) { }

    open(component: Type<any>, modalName: string) {
        const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
        var ref = factory.create(this.injector);
        this.applicationRef.attachView(ref.hostView);
        const domElement = (ref.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
        document.body.appendChild(domElement);
        ref.changeDetectorRef.detectChanges();
        ref.instance.open(component, modalName);
        this.refs.push(ref);
        return ref;
    }

    close(ref) {        
        this.applicationRef.detachView(ref.hostView);
        ref.instance.close();
        ref.destroy();
        // Remove ref from a list managed by the service
        var i = this.refs.indexOf(ref);
        this.refs.splice(i, 1);
    }

    closeAll()
    {       
        this.refs.forEach(r => this.close(r));
    }
}

Это не проверено и может потребоваться настройка, но вы должны получить идею. Вместо использования ComponentRef в качестве дескриптора вы также можете создать некоторый пользовательский объект, чтобы предотвратить непосредственное взаимодействие вызывающего объекта с компонентом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...