我无法让angular的DynamicComponentLoader在beta.6中工作
我从他们的文档中获取了动态组件加载的示例代码,并将其添加到plnkr中的工作入门代码中,请参见此处.
这是代码:
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');
}
}
Run Code Online (Sandbox Code Playgroud)
这是stacktrace,它说:"元素上没有组件指令":
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
Run Code Online (Sandbox Code Playgroud)
Eri*_*nez 16
不推荐使用DynamicComponentLoader(请参阅commit).现在正确的方法是使用ViewContainerRef和ComponentResolver(参见下面的更新3)获取构造函数中的示例.
在beta.1中有一个突破性的变化.您无法再访问构造函数中的视图.因此,您可以将该示例移动到ngOnInit(),它将起作用.
引用更改日志
调用组件构造函数时,尚未创建组件视图. - >使用onInit生命周期回调来访问组件的视图
export class AppComponent {
constructor(private dcl: DynamicComponentLoader, private elementRef: ElementRef) {
}
ngOnInit() {
this.dcl.loadIntoLocation(ChildComponent, this.elementRef, 'child');
}
}
Run Code Online (Sandbox Code Playgroud)
在您的示例工作时检查此plnkr.
仅为了您的信息,我发送了一个PR(参见#7186)来修复源代码中的示例.所以希望他们会审查它,它会通过.
由于loadIntoLocation删除了beta.16 并且错误不再可重现.loadNextToLocation现在需要一个ViewContainerRef.我打开了一个新的PR(参见#8241)来添加一个新的例子,其他一切已经被原始PR覆盖了.
代码示例(更新3)
如上所述现在没有,loadIntoLocation但通过使用ViewContainerRef和实现相同的行为ComponentResolver.
constructor(cmpResolver: ComponentResolver, viewContainer: ViewContainerRef) {
cmpResolver.resolveComponent(MyComponent)
.then((factory: ComponentFactory) => {
viewContainer.createComponent(factory, 0, viewContainer.injector)
});
}
Run Code Online (Sandbox Code Playgroud)
参考
关于loadNextToLocation,有两种方法,都使用ViewContainerRef.
ViewContainerRef元素本身constructor(private dcl: DynamicComponentLoader, viewContainer: ViewContainerRef) {
dcl.loadNextToLocation(MyComponent, viewContainer).then(ref => {});
}
Run Code Online (Sandbox Code Playgroud)
// 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 => {});
}
}
Run Code Online (Sandbox Code Playgroud)
以上为例的plnkr.
| 归档时间: |
|
| 查看次数: |
2670 次 |
| 最近记录: |