使用指令 Angular 时 @ViewChild 为空
@ViewChild is null when using Directive Angular
我正在关注有关如何在运行时动态加载组件的 this 教程,并且 运行 遇到了问题,我的 @ViewChild
是 undefined
。
这是我的指令`。
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[dynamic-event]'
})
export class EventDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
注入模板的组件(feed.component.html):
<ng-template dynamic-event></ng-template>
feed.component.ts
import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { Event } from '../../models/event';
import { FeedService } from '../../services/feed.service';
import { EventDirective } from '../../directives/event.directive';
import { EventComponent } from '../event.component/event.component';
@Component({
selector: 'app-feed',
templateUrl: './feed.component.html',
styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit {
//feeds
feeds: Event[];
//Get directive which contains ViewContainerRef
@ViewChild(EventDirective) eventHost: EventDirective;
constructor(private feedService: FeedService,
private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
//this.getFeeds();
}
ngAfterViewChecked() {
this.getFeeds();
}
getFeeds(): void {
this.feedService
.getFeeds()
.subscribe(o =>
{
this.feeds = o;
this.populateFeeds();
});
}
populateFeeds(): void {
//resolve my component dynamically
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(EventComponent);
//get FeedComponent's ViewContainer (serves as parent viewContainer)
let viewContainerRef = this.eventHost.viewContainerRef;
viewContainerRef.clear();
if (this.feeds !== undefined || this.feeds !== null || this.feeds.entries.length !== 0){
this.feeds.forEach(x => {
let component = viewContainerRef.createComponent(componentFactory);
(<EventComponent>component.instance).event = x;
});
}
}
}
我的 @ViewChild
未定义,我不确定为什么。有帮助吗?
我认为如果没有实际的原生 HTML 元素,您将无法做到这一点。
要验证,请尝试 <div dynamic-event></div>
ng-template
是虚拟元素,在使用(某处)之前不会放置在生成的 HTML 标记中 - 因此没有带有指令的元素,字段未定义。
我发现了我的问题。
因为我没有使用 Angular 的 cli 命令 ng generate directive
,它会在 app.module
声明数组中声明我的指令,所以我收到了这个错误。
我手动添加了我的 EventDirective
,现在可以使用了:
这是一个例子:
@NgModule({
declarations: [
AppComponent,
FeedComponent,
EventComponent,
EventDirective
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
entryComponents: [EventComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
我正在关注有关如何在运行时动态加载组件的 this 教程,并且 运行 遇到了问题,我的 @ViewChild
是 undefined
。
这是我的指令`。
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[dynamic-event]'
})
export class EventDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
注入模板的组件(feed.component.html):
<ng-template dynamic-event></ng-template>
feed.component.ts
import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { Event } from '../../models/event';
import { FeedService } from '../../services/feed.service';
import { EventDirective } from '../../directives/event.directive';
import { EventComponent } from '../event.component/event.component';
@Component({
selector: 'app-feed',
templateUrl: './feed.component.html',
styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit {
//feeds
feeds: Event[];
//Get directive which contains ViewContainerRef
@ViewChild(EventDirective) eventHost: EventDirective;
constructor(private feedService: FeedService,
private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
//this.getFeeds();
}
ngAfterViewChecked() {
this.getFeeds();
}
getFeeds(): void {
this.feedService
.getFeeds()
.subscribe(o =>
{
this.feeds = o;
this.populateFeeds();
});
}
populateFeeds(): void {
//resolve my component dynamically
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(EventComponent);
//get FeedComponent's ViewContainer (serves as parent viewContainer)
let viewContainerRef = this.eventHost.viewContainerRef;
viewContainerRef.clear();
if (this.feeds !== undefined || this.feeds !== null || this.feeds.entries.length !== 0){
this.feeds.forEach(x => {
let component = viewContainerRef.createComponent(componentFactory);
(<EventComponent>component.instance).event = x;
});
}
}
}
我的 @ViewChild
未定义,我不确定为什么。有帮助吗?
我认为如果没有实际的原生 HTML 元素,您将无法做到这一点。
要验证,请尝试 <div dynamic-event></div>
ng-template
是虚拟元素,在使用(某处)之前不会放置在生成的 HTML 标记中 - 因此没有带有指令的元素,字段未定义。
我发现了我的问题。
因为我没有使用 Angular 的 cli 命令 ng generate directive
,它会在 app.module
声明数组中声明我的指令,所以我收到了这个错误。
我手动添加了我的 EventDirective
,现在可以使用了:
这是一个例子:
@NgModule({
declarations: [
AppComponent,
FeedComponent,
EventComponent,
EventDirective
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
entryComponents: [EventComponent],
bootstrap: [AppComponent]
})
export class AppModule { }