Вместо назначения созданного модального компонента свойству 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
в качестве дескриптора вы также можете создать некоторый пользовательский объект, чтобы предотвратить непосредственное взаимодействие вызывающего объекта с компонентом.