【问题标题】:Display problems on Angular Elements with Material Dialog (ShadowDom issue?)使用材质对话框在 Angular 元素上显示问题(ShadowDom 问题?)
【发布时间】:2019-09-16 17:18:20
【问题描述】:

我将与 Angular 7 上的 Angular Elements 取得联系,以构建可以简单地部署在现有网页中的轻量级 Web 组件。 第一次测试很有希望,但是我在使用基于 Angular Material (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. ');
    });
  }
}

filter-dialog.component.ts:

@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();
  }

}

有人提示我为什么对话框没有按预期工作?

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

但是:在简单的网页中显示为 Angular Element/Web 组件 - 未分离对话框

我会感谢你所有的 cmets :-)

【问题讨论】:

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

标签: angular dialog element shadow-dom


【解决方案1】:

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

因此,您在 Shadow DOM 中导入的材质样式无法访问对话框。

查看相关问题:https://github.com/angular/components/issues/13837

【讨论】:

    【解决方案2】:

    这个错误不是模态和显示的问题。这是 CSS 文件的问题。我通过将css文件添加到html中来解决这个问题。试试添加这个:

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

    为了更好地做到这一点,我将 CSS 重写为组件 CSS,然后一切都会好起来的。您也可以尝试将所有 CSS 从 Material Dialog 和其他自定义 css 提取到一个文件中,然后将其包含到您的网站中。您还应该阅读 Angular 组件中的 ViewEncapsulation。

    【讨论】:

      猜你喜欢
      • 2016-10-17
      • 1970-01-01
      • 2021-08-22
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 2016-09-17
      • 2020-02-22
      • 1970-01-01
      相关资源
      最近更新 更多