2016-09-07 3 views
33

ComponentResolverが推奨されないため、RC4から動的コンポーネントローダーをRC5に更新しようとしています。私は、次のAngular2 RC 5.動的にロードされるコンポーネントのコンポーネントファクトリが見つかりません

@Component({ 
    selector: 'component-dispatcher', 
    template: `<div #container></div>` // Define the template here because of its brevity 
}) 
export class ComponentDispatcherComponent implements OnInit, OnDestroy { 
    @Input() component:any; // Some dynamic component to render 
    @Input() options:any; // Component configuration, optional 
    @Input() data:any;  // Data to render within the component 

    // Inject the dynamic component onto the DOM 
    @ViewChild("container", {read: ViewContainerRef}) container:ViewContainerRef; 

    private componentReference:ComponentRef<any>; 

    constructor(private resolver:ComponentFactoryResolver) { 
    } 

    ngOnInit() { 
     // Create our component now we're initialised 
     let componentFactory = this.resolver.resolveComponentFactory(this.component); 
     this.componentReference = this.container.createComponent(componentFactory); 
     this.componentReference.instance.data = this.data; 
     this.componentReference.instance.options = this.options; 
    } 

    ngOnDestroy() { 
     // If we have a component, make sure we destroy it when we lose our owner 
     if (this.componentReference) { 
      this.componentReference.destroy(); 
     } 
    } 
} 

にローダーを更新し、私は私のTextCellComponentやアプリのI内の他のコンポーネントでこれを行うときに動的に

@Component({ 
    selector: 'text-cell', 
    pipes: [IterableObjectPipe], 
    templateUrl: './text-cell.component.html', 
    styles: ['.fieldName { font-weight: bold; }'] 
}) 
export class TextCellComponent implements OnInit { 
    // Data to render within the component 
    @Input() data: any; 
    @Input() record: any; 

    // Configuration of what data to display 
    @Input() options: { 
     excludeFieldNames: boolean, 
     translation: string 
    }; 

    constructor() { 
    } 

    ngOnInit() { 
     setTimeout(() => { 
      //console.log('***************************** ngOnInit...textCell ***********************'); 
      this.options.translation = '' + (_.get(this.options, 'translation') || 'fields'); 
     }); 
    } 
} 

しかし、DOMに次のコンポーネントをロードしようとしてきました私は

の手順を完了した

ORIGINAL EXCEPTION: No component factory found for TextCellComponent 
ORIGINAL STACKTRACE: 
Error: No component factory found for TextCellComponent 
at NoComponentFactoryError.BaseException [as constructor]  
(webpack:///./~/@angular/core/src/facade/exceptions.js?:27:23) 
at new NoComponentFactoryError 

次のエラーを取得します

しかし、私は何かが欠けているようです。私はブートストラップにコンポーネントを追加しようとしました。どんな提案も役に立ちます。

EDIT

モジュール定義に

@NgModule({ 
    imports: [ 
     BrowserModule, 
     HttpModule, 
     FormsModule, 
     ReactiveFormsModule, 
     ...MATERIAL_MODULES 
    ], 
    declarations: [ 
     ...APPLICATION_PIPES, 
     ...APPLICATION_COMPONENTS, 
     ...APPLICATION_DIRECTIVES, 
     CygnusComponent, 
     // Component declarations 
     // TODO: refactor to appropriate modules 
     ... 
     ComponentDispatcherComponent, 
     TextCellComponent, 
     ... 
    ], 
    bootstrap: [ 
     ApplicationComponent 
    ], 
    providers: [ 
     ...APPLICATION_PROVIDERS, 
     AppStore 
    ] 
}) 
export class ApplicationComponent {} 
+0

どのモジュールでも 'TextCellComponent'を宣言しましたか? –

+0

はい、それは宣言配列 – JME

+0

のトップレベルモジュールで宣言され、 'ComponentDispatcherComponent'は同じモジュールにありますか? –

答えて

83

ロードされようとしているすべてのコンポーネントを追加する「を動的に」あなたのモジュールのentryComponentsセクションで宣言する必要があります。言い換えれば、あなたのようなもので終わる必要があります。

@NgModule({ 
    imports: [BrowserModule, HttpModule, FormsModule, ReactiveFormsModule, ...MATERIAL_MODULES], 
    declarations: [...APPLICATION_PIPES, ...APPLICATION_COMPONENTS, ...APPLICATION_DIRECTIVES, CygnusComponent, 
     // Component declarations 
     // TODO: refactor to appropriate modules 
     ... 
     ComponentDispatcherComponent, 
     TextCellComponent, 
     ... 
    entryComponents: [TextCellComponent] 
    bootstrap: [ApplicationComponent], 
    providers: [...APPLICATION_PROVIDERS, AppStore] 
}) 
export class ApplicationComponent{ 

あなたはTextCellComponent両方declarationsentryComponentsセクションをリストする必要があることに注意してください。

1

インポートパスを確認したい場合があります。私の場合、あるファイルのインポートは大文字を使用し、もう1つは小文字を使用していました。

//file 1 
import { IRComponent } from "./components/IR/IR.component"; 
//file 2 
import { IRComponent } from "./components/ir/ir.component"; 

ばらしはクロームネットワーク]タブにあった、私は、ファイルが(各スペルのために一回)を2回ロードされていたことに気づきました。

0

EntryComponentsとDeclarationsにコンポーネントを指定した場合でも、この問題が発生することがあります。

ような状況では、あなただけの以下のように他のすべてのコンポーネントの上に(ここではTextCellComponent)を、このコンポーネント名を入力する必要があります。

declarations: [ 
     TextCellComponent // Declared above 
     CygnusComponent, 
     ComponentDispatcherComponent, 
     ... 
    ] 

これもentryComponentsで行う必要があります。

希望に役立ちます。

関連する問題