当 TemplateRef 通过 @Input 传入时,Angular @ContentChildren QueryList 不会检测到更改

Mic*_*uso 5 templates angular2-template angular

我将从我的组件在托管组件上的使用开始:

<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>
Run Code Online (Sandbox Code Playgroud)

现在,我的组件的 .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.
      */
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

这是 的标记MyTemplatedComponent

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.
      */
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我了解QueryList<CustomComponent>仅在ngAfterContentInit(). 没有订阅它,CustomComponentQueryList有零个项目,所以它没有CustomComponent@Inputted 中找到 a TemplateRef。但是,changesQueryList<CustomComponent>没有被触发,所以我肯定找不到我的组件。

奇怪的是,我看到的一切,从@Input泰德TemplateRef的页面上,包括从标记CustomComponent。那么,MyTemplatedComponent 是否检测到我输入的模板引用并通过 显示它*ngTemplateOutlet,但QueryList找不到我的CustomComponent?


但是,现在,如果我更改@Input() contentTemplate: TemplateRef<any>@ContentChild('contentTemplate') contentTemplate: TemplateRef<any>,然后将模板放入这样的标签中<my-templated-component>

<ng-container *ngTemplateOutlet="contentTemplate">
</ng-container>
Run Code Online (Sandbox Code Playgroud)

QueryList changes 不会被触发,并从订阅,我能找到我CustomComponent

也许@ContentChild并且@ContentChildren只有当且仅当<ng-template>像上面所做的那样直接将组件的标记/选择器的直接子元素作为子元素时,它才会起作用。

但我不会总是以<my-templated-component>这种方式扑通一声,有时<ng-template #contentTemplate>甚至可能来自托管组件之外。

一切都很好,如果我想要做的是采取TemplateRefs和我的模板组件的地方显示出来,但我需要调查的内容TemplateRefs,我会收到各种目的。

如果@ContentChildren要求我将<ng-template>s 放在组件的标签中,那么等效的装饰器是什么(我认为没有,而且绝对没有@ViewChildren),如果sTemplateRef是通过 传递的@Input?有什么有效的解决方法吗?

最终,从模板化组件内部,我们如何找到TemplateRef传入的 s内部的某些组件@Input好像@ContentChildren QueryList<T>不起作用?