[angular] Angular2 재질 대화 상자에 문제가 있습니다-@ NgModule.entryComponents에 추가 했습니까?

https://material.angular.io/components/component/dialog에 있는 문서를 따르려고 하는데 왜 아래 문제가 있는지 이해할 수 없습니까?

내 구성 요소에 아래를 추가했습니다.

@Component({
  selector: 'dialog-result-example-dialog',
  templateUrl: './dialog-result-example-dialog.html',
})
export class DialogResultExampleDialog {
  constructor(public dialogRef: MdDialogRef<DialogResultExampleDialog>) {}
}

내 모듈에서 나는 추가했다

import { HomeComponent,DialogResultExampleDialog } from './home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog
  ],

// ...

그러나 나는이 오류가 발생합니다 ….

EXCEPTION: Error in ./HomeComponent class HomeComponent - inline template:53:0 caused by: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
    ErrorHandler.handleError @ error_handler.js:50
    next @ application_ref.js:346
    schedulerFn @ async.js:91
    SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
    SafeSubscriber.next @ Subscriber.js:172
    Subscriber._next @ Subscriber.js:125
    Subscriber.next @ Subscriber.js:89
    Subject.next @ Subject.js:55
    EventEmitter.emit @ async.js:77
    NgZone.triggerError @ ng_zone.js:329
    onHandleError @ ng_zone.js:290
    ZoneDelegate.handleError @ zone.js:246
    Zone.runTask @ zone.js:154
    ZoneTask.invoke @ zone.js:345
    error_handler.js:52 ORIGINAL EXCEPTION: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
    ErrorHandler.handleError @ error_handler.js:52
    next @ application_ref.js:346
    schedulerFn @ async.js:91
    SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
    SafeSubscriber.next @ Subscriber.js:172
    Subscriber._next @ Subscriber.js:125
    Subscriber.next @ Subscriber.js:89
    Subject.next @ Subject.js:55
    EventEmitter.emit @ async.js:77
    NgZone.triggerError @ ng_zone.js:329
    onHandleError @ ng_zone.js:290
    ZoneDelegate.handleError @ zone.js:246
    Zone.runTask @ zone.js:154
    ZoneTask.invoke @ zone.js:345



답변

당신은 entryComponents내부에 동적으로 생성 된 구성 요소를 추가해야 합니다@NgModule

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog
  ],
  entryComponents: [DialogResultExampleDialog]

참고 : 어떤 경우에는 entryComponents아래 게으른로드 된 모듈 이 작동하지 않습니다, 해결 방법은 당신에 넣어으로 app.module(루트)


답변

entryComponents아래 에서 사용해야 @NgModule합니다.

을 사용하여 추가 한 동적으로 추가 된 구성 요소를위한 것 ViewContainerRef.createComponent()입니다. entryComponents에 추가하면 오프라인 템플릿 컴파일러가 컴파일하고 팩토리를 만들도록 지시합니다.

라우팅 된 구성 요소를 DOM에 추가 하는 데 에도 사용 entryComponents되므로 경로 구성에 등록 된 구성 요소도 자동으로 추가됩니다.router-outletViewContainerRef.createComponent()

그래서 당신의 코드는

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog
  ],
  entryComponents: [DialogResultExampleDialog]


답변

이것은 동적 구성 요소 이므로 entryComponents아래에 추가하지 않았기 때문에 발생 @NgModule합니다.

간단히 거기에 추가하십시오.

@NgModule({
  /* ----------------- */
  entryComponents: [ DialogResultExampleDialog ] // <---- Add it here

Angular 팀이 어떻게 이야기 하는지 살펴보십시오 entryComponents.

entryComponents?: Array<Type<any>|any[]>

이 모듈을 정의 할 때 컴파일해야하는 구성 요소 목록을 지정합니다. 여기에 나열된 각 구성 요소에 대해 Angular는 ComponentFactory를 만들어 ComponentFactoryResolver에 저장합니다.

또한 다음을 @NgModule포함 하는 방법 목록입니다 entryComponents

보시다시피, entryComponents구성 요소 배열을 허용하는 것을 포함하여 모든 것은 선택 사항입니다 (물음표를보십시오) .

@NgModule({
  providers?: Provider[]
  declarations?: Array<Type<any>|any[]>
  imports?: Array<Type<any>|ModuleWithProviders|any[]>
  exports?: Array<Type<any>|any[]>
  entryComponents?: Array<Type<any>|any[]>
  bootstrap?: Array<Type<any>|any[]>
  schemas?: Array<SchemaMetadata|any[]>
  id?: string
})


답변

MatDialog서비스 내부 에서 사용하려는 경우 전화를 걸면 'PopupService'해당 서비스가 다음과 같은 모듈에 정의됩니다.

@Injectable({ providedIn: 'root' })

작동하지 않을 수 있습니다. 지연 로딩을 사용하고 있지만 관련이 있는지 확실하지 않습니다.

당신은해야합니다 :

  • PopupService사용하여 대화 상자를 여는 구성 요소에 직접 제공하십시오 [ provide: PopupService ]. 이를 통해 MatDialog구성 요소 의 인스턴스 를 DI와 함께 사용할 수 있습니다 . 구성 요소 호출 open은이 인스턴스의 대화 상자 구성 요소와 동일한 모듈에 있어야 한다고 생각합니다 .
  • 대화 상자 구성 요소를 app.module로 이동하십시오 (다른 답변이 말했듯이)
  • matDialog서비스를 요청할 때 참조를 전달 하십시오.

내 뒤죽박죽 대답을 합니다만, 요점은 그것이이다 인 providedIn: 'root'MatDialog이 구성 요소 오프 피기 백에 필요하기 때문에 일을 깨는된다.


답변

지연 로딩의 경우 지연 로딩 모듈에서 MatDialogModule 을 가져와야 합니다. 그런 다음이 모듈은 자체 가져온 MatDialogModule을 사용하여 입력 컴포넌트를 렌더링 할 수 있습니다 .

@NgModule({
  imports:[
    MatDialogModule
  ],
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog
  ],
  entryComponents: [DialogResultExampleDialog]


답변

재료 대화를 통합하는 것이 가능 하지만 , 사소한 기능의 복잡성이 매우 높다는 것을 알았습니다. 사소한 기능을 달성하려고하면 코드가 더 복잡해집니다.

그런 이유로 PrimeNG Dialog 를 사용하여 사용하기가 매우 간단했습니다.

m-dialog.component.html:

<p-dialog header="Title">
  Content
</p-dialog>

m-dialog.component.ts:

@Component({
  selector: 'm-dialog',
  templateUrl: 'm-dialog.component.html',
  styleUrls: ['./m-dialog.component.css']
})
export class MDialogComponent {
  // dialog logic here
}

m-dialog.module.ts:

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { DialogModule } from "primeng/primeng";
import { FormsModule } from "@angular/forms";

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    DialogModule
  ],
  exports: [
    MDialogComponent,
  ],
  declarations: [
    MDialogComponent
  ]
})
export class MDialogModule {}

컴포넌트의 html에 대화 상자를 추가하기 만하면됩니다.

<m-dialog [isVisible]="true"> </m-dialog>

PrimeNG PrimeFaces 문서 는 따르기 쉽고 매우 정확합니다.


답변

문서에entryComponents 지정된대로에 추가해야합니다 .

@NgModule({
  imports: [
    // ...
  ],
  entryComponents: [
    DialogInvokingComponent,
    DialogResultExampleDialog
  ],
  declarations: [
    DialogInvokingComponent,
    DialogResultExampleDialog
  ],
  // ...
})

다음 과 같이 정의 된 대화 상자가있는 앱 모듈 파일 의 전체 예 는 다음과 같습니다 entryComponents.