2016-02-19 14 views
7

non riesco a ottenere DynamicComponentLoader di angolare di lavorare in beta.6DynamicComponentLoader in Angular2 beta: "nessuna direttiva componente alla elemento"

ho preso il codice di esempio per la componente dinamica di carico from their docs, e ha aggiunto alla loro codice avviamento di lavoro in plnkr, see here.

Ecco il codice:

import {Component, DynamicComponentLoader, ElementRef} from 'angular2/core'; 


@Component({ 
    selector: 'child-component', 
    template: 'Child' 
}) 
class ChildComponent { 
} 


@Component({ 
    selector: 'my-app', 
    template: '<h1>My First Angular 2 App</h1><div #child></div>' 
}) 
export class AppComponent { 
    constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) { 
    dcl.loadIntoLocation(ChildComponent, elementRef, 'child'); 
    } 
} 

Ed ecco lo stacktrace, che dice: "Non c'è nessuna direttiva componente alla elemento":

EXCEPTION: Error during instantiation of AppComponent!.BrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2.dev.js:23083 ORIGINAL EXCEPTION: There is no component directive at element [object Object]BrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2.dev.js:23083 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2.dev.js:23083 Error: There is no component directive at element [object Object] 
    at new BaseException (angular2.dev.js:7351) 
    at AppViewManager_.getNamedElementInComponentView (angular2.dev.js:6441) 
    at DynamicComponentLoader_.loadIntoLocation (angular2.dev.js:12375) 
    at new AppComponent (run.plnkr.co/mk31ybnwEtsiX31r/app/app.component.ts!transpiled:33) 
    at angular2.dev.js:1420 
    at Injector._instantiate (angular2.dev.js:11459) 
    at Injector._instantiateProvider (angular2.dev.js:11395) 
    at Injector._new (angular2.dev.js:11385) 
    at InjectorInlineStrategy.instantiateProvider (angular2.dev.js:11149) 
    at ElementDirectiveInlineStrategy.init (angular2.dev.js:9081)BrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2.dev.js:23083 ERROR CONTEXT:BrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2.dev.js:23083 _ContextcomponentElement: nullelement: my-appinjector: Injector__proto__: _ContextBrowserDomAdapter.logError @ angular2.dev.js:23083 
angular2-polyfills.js:1152 DEPRECATION WARNING: 'dequeueTask' is no longer supported and will be removed in next major release. Use removeTask/removeRepeatingTask/removeMicroTask 

risposta

16

Update 4 (e ultimo)

DynamicComponentLoader è in fase di deprecazione (vedere commit). Ora il modo corretto è utilizzare ViewContainerRef e ComponentResolver (vedere l'aggiornamento 3 di seguito) per un esempio nel costruttore.



In beta.1 ci fu un cambiamento di rottura. Non è possibile accedere più alla vista nel costruttore. Quindi puoi spostare quell'esempio in ngOnInit() e funzionerà.

Citando dal changelog

vista componente non è ancora creata quando costruttore componente è chiamato. -> uso onInit del ciclo di vita di callback per accedere alla visualizzazione di un componente

export class AppComponent { 
    constructor(private dcl: DynamicComponentLoader, private elementRef: ElementRef) { 

    } 
    ngOnInit() { 
    this.dcl.loadIntoLocation(ChildComponent, this.elementRef, 'child'); 
    } 
} 

Scegli questa plnkr con il vostro esempio funzionante.

Aggiornamento

Per vostra informazione ho mandato un PR (vedi #7186) per fissare gli esempi nel codice sorgente. Quindi speriamo che lo rivedranno e passeranno.

Update 2

Dal beta.16 loadIntoLocation è stato rimosso e l'errore non è più riproducibile. loadNextToLocation ora prende uno ViewContainerRef. Ho aperto un nuovo PR (vedi #8241) per aggiungere un nuovo esempio di esso, tutto il resto è già coperto dal PR originale.

Esempio di codice (update 3)

Come menzionato sopra Non v'è alcuna loadIntoLocation ma lo stesso comportamento è ottenuto utilizzando ViewContainerRef e ComponentResolver.

constructor(cmpResolver: ComponentResolver, viewContainer: ViewContainerRef) { 

    cmpResolver.resolveComponent(MyComponent) 
    .then((factory: ComponentFactory) => { 
     viewContainer.createComponent(factory, 0, viewContainer.injector) 
    }); 
} 

Riferimento

Per quanto riguarda loadNextToLocation, ci sono due modi, entrambi utilizzano ViewContainerRef.

  • Uso ViewContainerRef dall'elemento stesso
constructor(private dcl: DynamicComponentLoader, viewContainer: ViewContainerRef) { 
    dcl.loadNextToLocation(MyComponent, viewContainer).then(ref => {}); 
} 
  • Utilizzando alcuni elementi della vista
// Assume the next view 
template : '<div #container></div>'; 

class MyClass { 
    @ViewChild('container', {read: ViewContainerRef}) container : ViewContainerRef; 

    constructor(private dcl: DynamicComponentLoader) {} 

    ngAfterViewInit() { 
     this.dcl.loadNextToLocation(MyDynamicCmp, this.container).then(ref => {}); 
    } 
} 

A plnkr con l'esempio precedente.

+0

eccellente, grazie! – Hoff

+0

Ti dispiacerebbe aggiornare il tuo codice di esempio per riflettere la modifica dell'API? – bodine

+1

@bodine fatto !!! –

Problemi correlati