ng-template 的 Angular Access 内部组件

问题描述 投票:0回答:2

假设我们有一个名为

TopComponent
的组件,其模板如下:

<ng-template #top>
    <inner-selector #inner></inner-selector>
</ng-template>

它的代码很简单:

//... imports ...

@Component({
  // selector, styles etc
})
export class TopComponent implements AfterViewInit {

  @ViewChild('top') topComp : NgbModal;
  // NgbModal is a type provided by some 3rd-party library
  // I can't modify it

  ngAfterViewInit() {
    // let's access the #inner component from here
  }
}

我可以使用以下代码访问

#top
组件:

@ViewChild('top') topComponent: TopComponent;

如何从同一个类访问

#inner
组件?

我尝试使用

@ContentChild('inner')
但仍然得到
undefined

PS.我知道我可以创建另一个组件,使用它代替

<ng-template>
并从中访问所有必要的子组件。但这可以通过某种方式避免吗?

angular components
2个回答
0
投票

模板 #top 需要加载到某个容器中才能存在于 DOM 中,并由 @ViewChild 获取。 最简单的方法是使用简单的结构指令。 在下面的示例中,NotReady是一个布尔值,在 ngInit 完成后设置为 false。

<div *ngIf="notReady else top"> 
    loading... 
</div>
<ng-template #top>
    <inner-selector #inner></inner-selector>
</ng-template>

注意 @ViewChild('top') 需要映射为 static:false,因为它可能在 ngOnInit() 之后才可用/存在。 然后在每个更改检测周期搜索 #top,这在使用 *ngIf 等条件指令时很有用。

//... imports ...

@Component({
  // selector, styles etc
})
export class TopComponent implements AfterViewInit {

  notReady: boolean = true;

  @ViewChild("top", { static: false })  topComp : NgbModal;
  // NgbModal is a type provided by some 3rd-party library
  // I can't modify it
  
  ngInit(){
    this.notReady = false;
  }

  ngAfterViewInit() {
    // let's access the #inner component from here
  }
}

-1
投票

使用后代 @ViewChild('inner', {descendants: true}) inner: InnerSelector;

这里是填充代码:https://plnkr.co/edit/MtVhHuAtPXZzC7GLOidF?p=preview

 @Component({
    selector: 'inner-selector',
    template:'inner-selector here'
  })
  export class InnerSelector {
    myVar = 0;
  }

  @Component({
    selector: 'my-app',
    template: `
      <div>
        <ng-template #top>
           <inner-selector #inner></inner-selector>
        </ng-template>

       <ng-container [ngTemplateOutlet]="top"></ng-container>
      </div>
    `,
  })
  export class App {
    @ViewChild('inner', {descendants: true}) inner: InnerSelector;
    constructor() {
      this.name = `Angular! v${VERSION.full}`
    }
    ngAfterViewInit() {
      console.log(this.inner);
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.