@ViewChild имеет значение null при использовании директивы Angular

Я следую руководству это о том, как динамически загружать компоненты во время выполнения, и столкнулся с проблемами, когда мой @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 не определен, и я не знаю почему. Любая помощь?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
0
848
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, вы не сможете этого сделать без собственно собственного HTML-элемента.

Для проверки попробуйте с <div dynamic-event></div>

ng-template является виртуальным элементом и не помещается в сгенерированную разметку HTML, пока не используется (где-то) - так как нет элемента с директивой, поле не определено.

Мой feed.component.html теперь выглядит так: <p> Здесь загружаются динамические события </p> <div> <ng-template dynamic-event> </ng-template> </div> К сожалению, @ViewChild все еще не определен

monstertjie_za 27.07.2018 11:48

чтобы быть более точным, сам ng-шаблон будет закомментирован в html, если он не упомянут в ngIf

Suraj Rao 27.07.2018 11:50

@monstertjie_za point устанавливает директиву для элемента html, такого как div

Suraj Rao 27.07.2018 11:50

@SurajRao этого не знал. Вы уверены, что это произойдет в производственной сборке? Может, это просто в режиме разработки?

Antoniossss 27.07.2018 11:51

@Antoniossss Я пробовал <div dynamic-event> </div>, не решил проблему

monstertjie_za 27.07.2018 11:53

Все еще не определено ?? Не могли бы вы создать stackblitz, чтобы воспроизвести это?

Antoniossss 27.07.2018 11:54

думаю будет пустой комментарий

Suraj Rao 27.07.2018 11:56

Здесь вы можете видеть, что я ввел свою настраиваемую директиву. stackblitz.com/edit/…

Antoniossss 27.07.2018 12:02

@Antoniossss Ваш ответ выше неверен. У меня он работает только с <ng-template dynamic-event> </ng-template> в качестве моего шаблона html

monstertjie_za 27.07.2018 12:52
Ответ принят как подходящий

Я нашел свою проблему.

Поскольку я не использовал команду 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 { }

Другие вопросы по теме