Angular @ContentChildren QueryList не обнаруживает изменений, когда TemplateRef передается через @Input - PullRequest
1 голос
/ 21 июня 2019

Я начну с использования моего компонента на компоненте хостинга:

<my-templated-component [content-template]="contentTemplate">
</my-templated-component>

<ng-template #contentTemplate>
  <h3>Hello There</h3>
  <div>Lorem ipsum..... </div>
  <custom-component></custom-component>
</ng-template>

Теперь, мой компонент .ts:

class MyTemplatedComponent implements AfterContentInit {
  @Input('content-template') contentTemplate: TemplateRef<any>;
  @ContentChildren(CustomComponent) customComponentQueryList: QueryList<CustomComponent>;

  ...
  ngAfterContentInit() {

    // Length is 0 at this point. My component didn't find the component I want
    console.log(`There are ${this.customComponentQueryList.length} items`);

    this.customComponentQueryList.changes.subscribe((s) => {
      /* This is not called. This is where I would have wanted to find
         my CustomComponent to perform a task that requires its presence.
      */
    });
  }
}

А вот разметка для MyTemplatedComponent:

<ng-container *ngTemplateOutlet="contentTemplate">
</ng-container>

Я понимаю, что QueryList<CustomComponent> будет доступен только на ngAfterContentInit().Без подписки на него CustomComponentQueryList не имеет элементов, поэтому он не нашел CustomComponent из @Input ted TemplateRef.Но changes из QueryList<CustomComponent> не запускается, поэтому я определенно не могу найти свой компонент.

Странно то, что я вижу все из этого @Input ted TemplateRef настраницы, включая разметку от CustomComponent.Итак, MyTemplatedComponent обнаруживает мой введенный шаблон ссылки и отображает его через *ngTemplateOutlet, но QueryList не может найти мой CustomComponent?


Теперь,однако, если я изменил @Input() contentTemplate: TemplateRef<any> на @ContentChild('contentTemplate') contentTemplate: TemplateRef<any>, а затем поместил шаблон внутри , теги <my-templated-component> выглядят так:

<my-templated-component>
  <ng-template #contentTemplate>
    <h3>Hello There</h3>
    <div>Lorem ipsum..... </div>
    <custom-component></custom-component>   
  </ng-template>
</my-templated-component>

QueryList changes срабатывает , и по подписке я могу найти мои CustomComponent.

Возможно @ContentChild и @ContentChildren будут работать только в том случае, если Я прямо положил <ng-template> как непосредственный дочерний элемент разметки / селектора моего компонента, как я делал выше.

Но я не всегда получу plop <my-templated-component> таким образом, и тамбудут времена, когда <ng-template #contentTemplate> может даже прийти извне хост-компонента.

Все хорошо, если все, что я хочу сделать, это взять TemplateRefs и отобразить их где-нибудь в моих шаблонных компонентах, но яВам нужно будет исследовать содержимое из TemplateRefs, которое я получу для различных целей.

Если @ContentChildren требует, чтобы япоместите мои <ng-template> в теги моего компонента, что будет эквивалентным декоратором (я не думаю, что он есть, и это определенно не @ViewChildren), если TemplateRef был передан через @Input?Есть ли эффективные обходные пути?

В конечном счете, изнутри шаблонных компонентов, как мы находим определенные компоненты внутри TemplateRef, передаваемые как @Input, если @ContentChildren QueryList<T> не работают?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...