Angular2 beta中的DynamicComponentLoader:“元素没有组件指令”

我不能让angular的DynamicComponentLoader在beta.6中工作

我已经为动态组件加载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');
  }
}

这里是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
更新4(和最后)

不推荐使用DynamicComponentLoader(参见commit).现在正确的方法是使用ViewContainerRef和ComponentResolver(请参阅下面的更新3)获取构造函数中的示例.

在beta.1中有一个突破性的变化.您无法再访问构造函数中的视图.因此,您可以将该示例移动到ngOnInit(),它将起作用.

引自changelog

Component view is not yet created when component constructor is called. -> use onInit lifecycle callback to access the view of a component

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,但使用ViewContainerRef和ComponentResolver可以实现相同的行为.

constructor(cmpResolver: ComponentResolver,viewContainer: ViewContainerRef) {

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

参考

> ViewContainerRef#createComponent
> ComponentResolver#resolveComponent

关于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.

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...