2016-02-19 43 views
7

「的元素沒有成分的指令」我不能讓角的DynamicComponentLoader在beta.6工作DynamicComponentLoader在Angular2測試:

我已經採取了動態元件裝配from their docs示例代碼,並將其添加到自己的工作起動碼爲plnkr, see here

下面的代碼:

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'); 
    } 
} 

這裏是堆棧跟蹤,它說: 「有一個在單元沒有成分的指令」:

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 

回答

16

更新4(最後)

DynamicComponentLoader正被棄用(請參閱commit)。現在正確的方法是在構造函數中使用ViewContainerRefComponentResolver(請參見下面的更新3)。



在beta.1有重大更改。您不能再訪問構造函數中的視圖。所以你可以將這個例子移動到ngOnInit(),它會起作用。

changelog

組件視圖引述當組分構造函數被調用還沒有被創建。 - >使用OnInit的生命週期回調訪問組件的

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

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

入住這plnkr你的榜樣工作的看法。

更新

只爲你的信息我已經發出了PR(見#7186)固定在源代碼中的例子。所以希望他們會審查它,它會通過。

更新2

由於beta.16 loadIntoLocation除去,錯誤不再重複的。 loadNextToLocation現在需要ViewContainerRef。我打開了一個新的PR(請參閱#8241)以添加它的一個新示例,其他所有內容已被原始PR覆蓋。

代碼示例(更新3)

如上所述現在不用loadIntoLocation但相同的行爲通過使用ViewContainerRefComponentResolver實現。

constructor(cmpResolver: ComponentResolver, viewContainer: ViewContainerRef) { 

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

參考

關於loadNextToLocation,有兩種方法,都使用ViewContainerRef

  • 使用ViewContainerRef從元件本身
constructor(private dcl: DynamicComponentLoader, viewContainer: ViewContainerRef) { 
    dcl.loadNextToLocation(MyComponent, viewContainer).then(ref => {}); 
} 
  • 上視圖
// 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 => {}); 
    } 
} 

plnkr與上面的例子中使用一些元件。

+0

非常好,謝謝! – Hoff

+0

您是否介意更新您的示例代碼以反映API更改? – bodine

+1

@bodine完成! –