简体   繁体   中英

MatDialog not rendering inside custom OverlayContainer in angular 15

In Angular 15, if a component is provided with OverlayContainer and overridden to use it as a custom container element, individual overlay elements are not rendering inside the container (), instead is appended to the document body(default behaviour).

@Injectable()
export class OverlayService extends OverlayContainer{
    constructor(
      @Inject(DOCUMENT) _document: any,
      platform: Platform,
      private problem: ElementRef<HTMLElement>
    ) {
      super(_document, platform);
    }

    protected override _createContainer(): void {
      const containerClass = "cdk-overlay-container";
      const container = this._document.createElement("div");
      container.classList.add(containerClass);

      this.problem.nativeElement.appendChild(container);
      this._containerElement = container;
    }

}
@Component({
  selector: 'app-problem',
  templateUrl: './problem.component.html',
  styleUrls: ['./problem.component.css'],
  providers: [
    DialogServiceService,
    MatDialog,
    { provide: OverlayContainer, useClass: OverlayService },
  ],
})

Current behaviour:

<body>
  <app-problem></app-problem>
</body>
<div class="cdk-overlay-container">
  <mat-dialog-container></mat-dialog-container>
</div>

https://stackblitz.com/edit/angular-pfwikb?file=src%2Fapp%2Fproblem%2Fproblem.component.ts

I was expecting the MatDialog to render inside the custom container as in previous angular versions.

Expected behaviour:

<body>
 <app-problem>
   <div>....</div>
   <div class="cdk-overlay-container">
      <mat-dialog-container></mat-dialog-container>
   </div>
 </app-problem>
</body>

I haven't migrated any of the apps to v15 (and probably won't anytime soon), so I can't give you full working solution - but perhaps I will at least be able to push you in the right direction.

If you take a look at the constructor of MatDialogBase you'll notice that while OverlayContainer is still injected, it's documented as deprecated and no longer used. That's why your MatDialog is still rendered in the default cdk-overlay-container .

MatDialog docs don't mention anything about changing the container in which the dialog will be rendered. If you dig a little bit deeper into the source you'll see that it will be rendered in the MatDialogContainer - but it seems that this is not configurable as it's explicitly typed in MatDialog and not exposed in the MatDialogConfig . So unless I'm missing something (and it's quite possible I am), you can't change the container anymore. I think your best bet is create an issue in the github of angular/components repo - if there's a way, I'm sure you get a response from them with an example, especially since it seems like a huge regression.

Luckily, since v14 there is an alternative to MatDialog - namely CdkDialog upon which it's built. In there, the DialogConfig exposes a container property, which allows you specifying a component type or factory for a component in which the dialog will be rendered. The downside is that you'll lose the material styling and will have to apply your own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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