Angular 使用“材质”对话框显示角度元素上的问题(阴影问题?)

Angular 使用“材质”对话框显示角度元素上的问题(阴影问题?),angular,dialog,element,shadow-dom,Angular,Dialog,Element,Shadow Dom,我将接触Angular 7上的Angular元素,以构建轻量级web组件,这些组件可以简单地部署在现有网页中。 第一次测试很有希望,但是我在基于角度材质的对话框(MatDialog)上遇到了显示问题。 如果我将Angular组件(FilterComponent)构建为Angular元素,并在一个简单的HTML5网页中运行生成的web组件,则对话框将直接显示在基本网页上,而不是分离的对话框 我使用当前稳定的Angular/cli 7.3.8版本 app.module.ts: @NgModule({

我将接触Angular 7上的Angular元素,以构建轻量级web组件,这些组件可以简单地部署在现有网页中。 第一次测试很有希望,但是我在基于角度材质的对话框(MatDialog)上遇到了显示问题。 如果我将Angular组件(FilterComponent)构建为Angular元素,并在一个简单的HTML5网页中运行生成的web组件,则对话框将直接显示在基本网页上,而不是分离的对话框

我使用当前稳定的Angular/cli 7.3.8版本

app.module.ts:

@NgModule({
  declarations: [
    AppComponent,
    SearchElementComponent,
    FilterDialogComponent,
    FilterComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    MaterialModule,
    ReactiveFormsModule,
  ],
  entryComponents: [SearchElementComponent, FilterComponent, FilterDialogComponent]
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    // Convert `SearchElementComponent` to a custom element.
    const SearchElementElement = createCustomElement(SearchElementComponent, {injector: this.injector});
    // Register the custom element with the browser.
    customElements.define('search-element', SearchElementElement);

    const FilterComponentElement = createCustomElement(FilterComponent, {injector: this.injector});
    customElements.define('filter-element', FilterComponentElement);
  }
}
filter.component.ts:

@Component({
  selector: 'app-filter',
  template: `
    <button mat-mini-fab class="filer-button" (click)="openFilterDialog()" title="Filter">
      <i class="material-icons filter-icon">filter_list</i>
    </button>
  `,
  styleUrls: ['./filter.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterComponent {
  topicMedical = true;
  topicPharma = true;
  topicBiotec = true;

  constructor(
    public dialog: MatDialog,
  ) { }

  public openFilterDialog(): void {
    const dialogRef = this.dialog.open(FilterDialogComponent, {
      panelClass: 'filterDialog',
      autoFocus: false,
      minWidth: 350,
      maxWidth: '60%',
      maxHeight: '45%',
      data: {
        topicMedical: this.topicMedical,
        topicPharma: this.topicPharma,
        topicBiotec: this.topicBiotec,
      }
    });
    dialogRef.afterClosed().subscribe(data => {
      console.log('Filter dialog closed. ');
    });
  }
}
@Component({
  selector: 'app-filter-dialog',
  templateUrl: './filter-dialog.component.html',
  styleUrls: ['./filter-dialog.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterDialogComponent {


  constructor(
    public dialogRef: MatDialogRef<FilterDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: FilterDialogData) { }

  onNoClick(): void {
    this.dialogRef.close();
  }

}
@组件({
选择器:“应用程序筛选器”,
模板:`
过滤列表
`,
样式URL:['./filter.component.css'],
封装:viewEn封装.ShadowDom
})
导出类筛选器组件{
topicMedical=true;
topicPharma=true;
topicBiotec=真;
建造师(
公共对话:MatDialog,
) { }
公共openFilterDialog():void{
const dialogRef=this.dialog.open(FilterDialogComponent{
panelClass:“filterDialog”,
自动对焦:错误,
最小宽度:350,
maxWidth:'60%',
最大高度:“45%”,
数据:{
topicMedical:this.topicMedical,
topicPharma:this.topicPharma,
topicBiotec:this.topicBiotec,
}
});
dialogRef.afterClosed().subscribe(数据=>{
log('过滤器对话框关闭');
});
}
}
filter-dialog.component.ts:

@Component({
  selector: 'app-filter',
  template: `
    <button mat-mini-fab class="filer-button" (click)="openFilterDialog()" title="Filter">
      <i class="material-icons filter-icon">filter_list</i>
    </button>
  `,
  styleUrls: ['./filter.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterComponent {
  topicMedical = true;
  topicPharma = true;
  topicBiotec = true;

  constructor(
    public dialog: MatDialog,
  ) { }

  public openFilterDialog(): void {
    const dialogRef = this.dialog.open(FilterDialogComponent, {
      panelClass: 'filterDialog',
      autoFocus: false,
      minWidth: 350,
      maxWidth: '60%',
      maxHeight: '45%',
      data: {
        topicMedical: this.topicMedical,
        topicPharma: this.topicPharma,
        topicBiotec: this.topicBiotec,
      }
    });
    dialogRef.afterClosed().subscribe(data => {
      console.log('Filter dialog closed. ');
    });
  }
}
@Component({
  selector: 'app-filter-dialog',
  templateUrl: './filter-dialog.component.html',
  styleUrls: ['./filter-dialog.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterDialogComponent {


  constructor(
    public dialogRef: MatDialogRef<FilterDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: FilterDialogData) { }

  onNoClick(): void {
    this.dialogRef.close();
  }

}
@组件({
选择器:“应用程序筛选器对话框”,
templateUrl:'./filter dialog.component.html',
样式URL:['./过滤器对话框.component.css'],
封装:viewEn封装.ShadowDom
})
导出类FilterDialogComponent{
建造师(
公共dialogRef:MatDialogRef,
@注入(MAT_DIALOG_DATA)公共数据:FilterDialogData{}
onNoClick():void{
this.dialogRef.close();
}
}
有没有人给我一个提示,为什么对话框不能按预期工作

按预期显示为常规角度应用程序

但是:在简单网页中显示为角度元素/web组件-未分离对话框


非常感谢您的所有评论:-)

包含“FilterComponent”的材质对话框可能已附加到body元素

因此,在阴影DOM中导入的材质样式无法访问该对话框


请参阅相关问题:

此错误不是模态和显示模态的问题。这是CSS文件的一个问题。我通过在html中添加css文件来解决这个问题。尝试添加以下内容:

<link href="node_modules/@angular/material/prebuilt-themes/indigo-pink.css" rel="stylesheet">


为了以一种好的方式做到这一点,我将CSS重写为组件CSS,然后一切都会好起来。您还可以尝试将“材质”对话框和其他自定义CSS中的所有CSS提取到一个文件中,然后将其包含到您的网站中。您还应该了解角度组件中的视图封装。

您是如何构建应用程序的?您是否在web元素中包含zone.js?也许angular没有正确检查更改?尝试使用
ChangeDetectorRef
并在对话框打开后手动触发更改检测(
this.ChangeDetectorRef.detectChanges()
)@OleksiiMiroshnyk:感谢您的回复。通常,我使用ngx build plus构建web组件,并将zone.js手动加载到web页面(index.html)。我理解您的提示,我尝试添加
dialogRef.afterOpened().subscribe(=>this.changeDetectorRef.detectChanges())编码到filter.components.ts文件中。但是,显示行为没有改变。我明白你的权利吗?或者我应该如何在代码中实现您的提示?是的,您做到了,除非我下一步想做:
this.dialog.open();this.changeDetectirRef.detectChanges()如果对话框在自定义元素中正确打开,则需要检查是否包含所有样式。也许你没有包括cdk覆盖样式到你的自定义元素构建。再次感谢。然而,在我放入
this.changedethetectorref.detectChanges()之后,没有任何变化
直接在
这个.dialog.open()之后。我还尝试将cdk覆盖样式包括到filter.component.css文件
@import'../../../node_modules/@angular/cdk/overlay prebuild.css'不改变显示行为。或者我应该如何在自定义元素中包含cdk覆盖样式?