Skip to content

Commit

Permalink
Angular: Extract DxPopupServiceComponent type (#27992)
Browse files Browse the repository at this point in the history
  • Loading branch information
GoodDayForSurf authored Sep 10, 2024
1 parent 459dba5 commit bcdcdbb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 32 deletions.
2 changes: 1 addition & 1 deletion packages/devextreme-angular/src/ui/popup/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './component';
export { DxPopupService } from './service/service';
export { DxPopupService, DxPopupServiceComponent } from './service/service';
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import {
AfterViewInit,
Component, ComponentRef,
ElementRef,
EventEmitter, Inject,
Inject,
NgZone,
Output, PLATFORM_ID,
TransferState,
PLATFORM_ID,
TransferState, Type,
ViewChild,
} from '@angular/core';
import {
Expand All @@ -14,7 +14,7 @@ import {
NestedOptionHost,
WatcherHelper,
} from 'devextreme-angular/core';
import { DxPopupComponent } from '../component';
import { DxPopupComponent, DxPopupTypes } from '../component';
import { DxServicePopupInsertionDirective } from './insertion.directive';

@Component({
Expand All @@ -28,28 +28,33 @@ import { DxServicePopupInsertionDirective } from './insertion.directive';
],
template: '<ng-template popup-content-insertion></ng-template>',
})
export class DxServicePopupComponent extends DxPopupComponent implements AfterViewInit {
export class PopupServiceComponent<T> extends DxPopupComponent implements AfterViewInit {
@ViewChild(DxServicePopupInsertionDirective) contentInsertion: DxServicePopupInsertionDirective;

@Output() afterViewInit$: EventEmitter<void> = new EventEmitter<void>();

contentRef: ComponentRef<unknown>;
contentRef: ComponentRef<T>;

constructor(
elementRef: ElementRef,
ngZone: NgZone,
templateHost: DxTemplateHost,
_watcherHelper: WatcherHelper,
_idh: IterableDifferHelper,
optionHost: NestedOptionHost,
transferState: TransferState,
@Inject(PLATFORM_ID) platformId: any,
@Inject('popupServiceContentComponent') private contentComponent: Type<T>,
@Inject('popupServiceOptions') private popupOptions: DxPopupTypes.Properties,
elementRef: ElementRef,
ngZone: NgZone,
templateHost: DxTemplateHost,
_watcherHelper: WatcherHelper,
_idh: IterableDifferHelper,
optionHost: NestedOptionHost,
transferState: TransferState,
@Inject(PLATFORM_ID) platformId: any,
) {
super(elementRef, ngZone, templateHost, _watcherHelper, _idh, optionHost, transferState, platformId);
}

ngAfterViewInit() {
super.ngAfterViewInit();
this.afterViewInit$.emit();

if(this.popupOptions) {
this.instance.option(this.popupOptions)
}

this.contentRef = this.contentInsertion?.viewContainerRef.createComponent(this.contentComponent);
}
}
30 changes: 16 additions & 14 deletions packages/devextreme-angular/src/ui/popup/service/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
EmbeddedViewRef,
ComponentRef, Type,
} from '@angular/core';
import { DxPopupTypes } from '../component';
import { DxServicePopupComponent } from './service.component';
import { DxPopupComponent, DxPopupTypes } from '../component';
import { PopupServiceComponent } from './service.component';

export type DxPopupServiceComponent<T = any> = DxPopupComponent & { contentRef: ComponentRef<T> }

@Injectable({
providedIn: 'root',
Expand All @@ -19,22 +21,22 @@ export class DxPopupService {
private readonly componentFactoryResolver: ComponentFactoryResolver,
) {}

open<T>(contentComponent: Type<T>, popupOptions?: DxPopupTypes.Properties) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DxServicePopupComponent);
const componentRef: ComponentRef<DxServicePopupComponent> = componentFactory.create(this.injector);
open<T>(contentComponent: Type<T>, popupOptions?: DxPopupTypes.Properties): DxPopupServiceComponent<T> {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(PopupServiceComponent<T>);
const serviceInjector = Injector.create({
providers: [
{ provide: 'popupServiceContentComponent', useValue: contentComponent },
{ provide: 'popupServiceOptions', useValue: popupOptions },
],
parent: this.injector
});
const componentRef = componentFactory.create(serviceInjector);
const cmpInstance = componentRef.instance;

cmpInstance.onHidden.subscribe(() => {
this.applicationRef.detachView(componentRef.hostView);
componentRef.destroy();
});

cmpInstance.afterViewInit$.subscribe(() => {
if (popupOptions) {
cmpInstance.instance.option(popupOptions);
}

componentRef.instance.contentRef = cmpInstance.contentInsertion?.viewContainerRef.createComponent(contentComponent);
componentRef.destroy();
});

this.applicationRef.attachView(componentRef.hostView);
Expand All @@ -47,6 +49,6 @@ export class DxPopupService {

this.applicationRef.tick();

return componentRef.instance as (typeof componentRef.instance & { contentRef: ComponentRef<T> });
return componentRef.instance;
}
}

0 comments on commit bcdcdbb

Please sign in to comment.