【问题标题】:Angular Material: 'mat-dialog-content' is not a known elementAngular Material:“mat-dialog-content”不是已知元素
【发布时间】:2020-07-02 12:14:11
【问题描述】:

在将此问题标记为“重复”之前,请听我说完,因为我被这个问题困扰了好几个小时。我已经解决了现有的问题,但找不到任何解决方案。

我正在学习 Angular,并开始使用 Angular 9+ 和 Angular Material。我正在尝试通过阅读official page 中的文档来实现一个简单的 Angular Material 对话框。

我的代码与示例代码非常相似,但我不知道为什么我仍然收到此错误消息:

'mat-dialog-content' is not a known element.
'mat-dialog-actions' is not a known element.

对话框确实出现了,但看起来好像在对话框模板 html 中根本没有渲染任何 Angular Material 组件/指令。即使我使用<button mat-button>Button</button>,它也会呈现为普通按钮而不是 Angular Material 按钮。不在对话框模板中的其他所有内容都可以正常工作。我不知道我在这里做错了什么,但如果有人能指出我的错误,那就太好了!

app.module.ts:(我正在导入MatDialogModule

...
import { MatDialogModule } from '@angular/material/dialog';

@NgModule({
    declarations: [
        ...
    ],
    imports: [
        ...
        MatDialogModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

mycomponent.ts:

import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import { MatDialog, MatDialogModule, MAT_DIALOG_DATA, MatDialogConfig } from '@angular/material/dialog';
...

@Component({
  selector: 'app-my',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {

    constructor(public dataDialogHandler: MatDialog) {}

    ngOnInit(): void {}

    public openDataDialog(): void {

        const dialogConfig = new MatDialogConfig();

        dialogConfig.data = {};

        this.dataDialogHandler.open(DataDialogComponent, dialogConfig);
    }
}

@Component({
    selector: 'data-dialog',
    templateUrl: './data-dialog.html'
})
export class DataDialogComponent {

    constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
}

export interface DialogData {}

data-dialog.html:

<h2 mat-dialog-title>some title</h2>
<mat-dialog-content>
    <p>dialog works</p>
</mat-dialog-content>
<mat-dialog-actions align="end">
    <button mat-button mat-dialog-close>Close</button>
</mat-dialog-actions>

最后,my.component.html:

<button mat-button (click)="openDataDialog()">View Dialog</button>

我在这里做错了什么?提前致谢!

@angular/core 9.0.7
@angular/cdk 9.1.3
@angular/material 9.1.3
typescript 3.7.5

【问题讨论】:

    标签: angular typescript angular-material angular-components


    【解决方案1】:

    您缺少entryComponents 声明。

    同时为DialogData添加接口

    export interface DialogData {
     example: string;
    }
    

    直播:https://stackblitz.com/edit/angular-q4mwkt

    MatDialog - Medium Post

    【讨论】:

    • 我试过这个,将DataDialogComponents 添加到entryComponents。但这仍然不能解决问题。
    • 使用您共享的确切代码对我来说效果很好 - stackblitz.com/edit/angular-q4mwkt
    • 确保您在 package.json 中有兼容版本的 core、common、compiler、cdk、material 和 animations
    • 也进行拼写检查。我看到您在 cmets 中提到了 DataDialogComponents,而在问题中它是单数形式的 DataDialogComponent
    • 我认为你的问题是 mat-dialog 没有出现。如果要使用它们,则必须导入每个材料模块。现在我也通过导入 mat-button 模块更新了 stackblitz。
    【解决方案2】:

    请在声明数组和app.module.ts的entryComponents数组中添加DataDialogComponent

    import { MatDialogModule } from '@angular/material/dialog';
    
    @NgModule({
        declarations: [
           DataDialogComponent //I think you have missed this declaration
        ],
        imports: [
            ...
            MatDialogModule
        ],
        providers: [],
       entryComponents: [DataDialogComponent]
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    【讨论】:

    • MyComponent 已与 AppComponent 一起添加到声明中。但这并不能解决问题。
    • DataDialogComponent 怎么样?是否也添加到声明数组中?
    • @SajibAcharya,如果这对您有帮助,请接受答案。
    【解决方案3】:

    mat-dialog-contentmat-dialog-actions 更改为属性。 即:

    <div mat-dialog-content>
        <p>dialog works</p>
    </div>
    <div mat-dialog-actions align="end">
        <button mat-button mat-dialog-close>Close</button>
    </div>
    

    【讨论】:

    • 这解决了我使用 Angular 11 的问题
    • 我正在从 angular & material 7 迁移到 11 。 Ng update 应该注意这一点,但没有。我必须手动进行更改。
    • 弄清楚这一点非常令人沮丧。非常感谢。
    【解决方案4】:

    我遇到了同样的问题,并通过将对话框组件和容器组件移动到不同的文件中来解决它。目前,您已经完成了这样的设置,其中对话框和容器组件都在同一个文件中声明:

    # my.component.ts
    
    @Component({
      selector: 'app-my',
      templateUrl: './my.component.html',
      styleUrls: ['./my.component.css']
    })
    export class MyComponent implements OnInit {
    
        constructor(public dataDialogHandler: MatDialog) {}
    
        ngOnInit(): void {}
    
        public openDataDialog(): void {
    
            const dialogConfig = new MatDialogConfig();
    
            dialogConfig.data = {};
    
            this.dataDialogHandler.open(DataDialogComponent, dialogConfig);
        }
    }
    
    @Component({
        selector: 'data-dialog',
        templateUrl: './data-dialog.html'
    })
    export class DataDialogComponent {
    
        constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
    }
    
    export interface DialogData {}
    

    将组件拆分为单独的文件

    我建议创建一个全新的对话框组件来处理它自己的依赖项,以便您最终得到这样的结果:

    # my.component.ts
    
    import { Component} from '@angular/core';
    import{ MatDialog } from '@angular/material/dialog';
    
    # Make sure you import your newly created component
    import{ MyDataDialog } from 'src/app/wherever-youve-put-it/my-data-dialog.component';
    
    @Component({
      selector: 'app-my',
      templateUrl: './my.component.html',
      styleUrls: ['./my.component.css']
    })
    export class MyComponent implements OnInit {
    
        constructor(public dataDialogHandler: MatDialog) {}
    
        ngOnInit(): void {}
    
        public openDataDialog(): void {
    
            const dialogConfig = new MatDialogConfig();
    
            dialogConfig.data = {};
    
            this.dataDialogHandler.open(MyDataDialogComponent, dialogConfig);
        }
    }
    

    然后使用ng generate component my-data-dialog 创建一个新组件作为您的对话框。然后,您可以跨依赖项和代码复制到(如果您使用 CLI 生成并复制而不是复制到新的手工组件中,您将不太可能得到引用等错误)

    # my-data-dialog.component.ts
    
    import { Component, OnInit, Inject} from '@angular/core';
    import{ MAT_DIALOG_DATA } from '@angular/material/dialog';
    
    @Component({
        selector: 'data-dialog',
        templateUrl: './data-dialog.html'
    })
    export class DataDialogComponent {
    
        constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
    }
    
    export interface DialogData {}
    

    【讨论】:

    • 所以我尝试了几种方法。我发现它 100% 工作的方法是在 1app.module` 的声明中添加对话框组件,并将 MatDialogModule 和(可选)MatButtonModule 导入到 app.module 的导入中。奇怪的是这出于某种原因。
    【解决方案5】:

    终于找到了解决问题的办法!

    需要在这里回答,因为我认为这是同一件事。它肯定会帮助很多人!

    所以,有两个问题:首先是您没有导出“MyComponent”。

    @NgModule({
        declarations: [
            ...
        ],
        imports: [
            ...
            MatDialogModule
        ],
        providers: [],
        bootstrap: [AppComponent]
        exports: [ AppComponent,         #add this code
                  MyComponent ],
    })
    

    似乎 Angular 无法将您的导入绑定到未导出的类中。那么这解决了HTML文件中的问题。 现在是第二个:为了测试,在“module.ts”中添加组件后,您还需要在“spec.ts”中添加 MatDialogModule:

    beforeEach(async() => {
    await TestBed.configureTestingModule({
      imports: [ CommonModule,
        ...,
        MatDialogModule],
    

    在这些更改之后,它运行良好。

    【讨论】:

      【解决方案6】:

      似乎当前的 Material 文档:

      <h2 mat-dialog-title>Delete all elements?</h2>
      

      这将删除当前在此页面上且无法撤消的所有元素。 取消

      here

      不适用于 Angular 12。Danilo Mz 的上述解决方案对我有用。

      即:“ 将 mat-dialog-content 和 mat-dialog-actions 更改为属性"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-20
        • 2019-06-27
        • 2019-02-02
        • 1970-01-01
        • 2020-11-15
        相关资源
        最近更新 更多