代码之家  ›  专栏  ›  技术社区  ›  nipuna777

@ContentChildren未拾取自定义组件内的项

  •  6
  • nipuna777  · 技术社区  · 6 年前

    我想用 @ContentChildren 使用 #buttonItem 标签

    @ContentChildren('buttonItem', { descendants: true })
    

    当父组件中直接有ref项时,这就起作用了。

    <!-- @ContentChildren returns child item -->
    <parent-component>
      <button #buttonItem></button>
    <parent-component>
    

    但是,如果 #钮扣 ref封装在自定义组件中,该组件不会被 @满足的孩子 即使我设定了 {descendants: true} 选项

    <!-- @ContentChildren returns empty -->
    <parent-component>
      <child-component-with-button-ref></child-component-with-button-ref>
    <parent-component>
    

    StackBlitz example 证明这一点。

    1 回复  |  直到 4 年前
        1
  •  4
  •   Marshal    6 年前

    似乎不是通过github解决此项目的时间表。。。我还发现一条评论,指出您无法跨越ng内容边界进行查询。

    https://github.com/angular/angular/issues/14320#issuecomment-278228336

    下面是可能的解决方法,可以让元素从 OptionPickerComponent .


    enter image description here


    在里面 计数 #listItem 然后发射阵列 AfterContentInit

     @Output() grandchildElements = new EventEmitter();     
     @ViewChildren('listItem') _items
    
      ngAfterContentInit() {
        setTimeout(() => {
            this.grandchildElements.emit(this._items)
        })
      } 
    

    设置模板引用 #picker ,注册至 (grandchildElements) $event picker.grandchildElements

     <app-option-picker #picker [optionList]="[1, 2, 3]" (grandchildElements)="picker.grandchildElements = $event" popup-content>
    

    在上创建输入 PopupComponent 接受来自

    @Input('grandchildElements') grandchildElements: any
    

    在里面 app.component.html 拾音器元件 输入

    <app-popup [grandchildElements]="picker.grandchildElements">
    

    popup.component 设置 console.log

    open() {
        if (this.grandchildElements) {
          console.log(this.grandchildElements);
        }
        else {
          console.log(this.childItems);
        }
    
     close() {
         if (this.grandchildElements) {
          console.log(this.grandchildElements);
        }
        else {
          console.log(this.childItems);
        }
    

    弹出窗口组件 换衣服 ContentChildren 回到 listItem

    @ContentChildren('listItem', { descendants: true }) childItems: Element;
    

    popup.component.html

    <h3>Child Items: {{grandchildElements ? grandchildElements.length : childItems.length}}</h3>
    

    闪电战

    https://stackblitz.com/edit/angular-popup-child-selection-issue-bjhjds?embed=1&file=src/app/option-picker/option-picker.component.ts

        2
  •  2
  •   cyberblast    4 年前

    我也有同样的问题。我们正在使用剑道组件进行角度分析。需要将列定义为网格组件的ContentChild。当我想把它包装成一个自定义组件并试图通过ng内容提供额外的列时,它根本不起作用。

    通过在自定义包装组件的ViewInit之后重置网格组件的QueryList,我成功地使其工作。

      @ViewChild(GridComponent, { static: true })
      public grid: GridComponent;
    
      @ContentChildren(ColumnBase)
      columns: QueryList<ColumnBase>;
    
      ngAfterViewInit(): void {
        this.grid.columns.reset([...this.grid.columns.toArray(), ...this.columns.toArray()]);
        this.grid.columnList = new ColumnList(this.grid.columns);
      }
    
        3
  •  0
  •   Kevin Beal    4 年前

    一个选项是重新绑定到内容子级。

    <outer-component>
      <content-child [someBinding]="true" (onEvent)="someMethod($event)">
          e.g. inner text content
      </content-child>
    </outer-component>
    

    在这个例子里面是虚构的 <outer-component> :

    @Component()
    class OuterComponent {
      @ContentChildren(ContentChild) contentChildren: QueryList<ContentChild>;
    }
    

    以及 <外部组件> 添加 <content-child> 组件,重新绑定到它:

    <inner-template>
      <content-child
        *ngFor="let child of contentChildren?.toArray()"
        [someBinding]="child.someBinding"
        (onEvent)="child.onEvent.emit($event)"
      >
          <!--Here you'll have to get the inner text somehow-->
      </content-child>
    </inner-template>
    

    根据您的情况,获取内部文本可能是不可能的。如果你能完全控制虚构的故事 < 您可以公开对元素ref的访问的组件:

    @Component()
    class ContentChildComponent {
      constructor(public element: ElementRef<HTMLElement>)
    }
    

    然后,当您重新绑定到它时,您可以添加 [innerHTML] 结合:

    <content-child
      *ngFor="let child of contentChildren?.toArray()"
      [someBinding]="child.someBinding"
      (onEvent)="child.onEvent.emit($event)"
      [innerHTML]="child.element.nativeElement.innerHTML"
    ></content-child>
    

    你可能不得不 sanitize the input [innerHTML]