ngFor

时间:2017-05-16 07:53:36

标签: angular ng-bootstrap

我正在尝试使用@ViewChild的ng-bootstrap选项卡中的ngFor来获取组件实例,但是我只是获取第一个组件实例,即使我正在更改选项卡以及component及其inputs

更新

我甚至尝试使用`@ViewChildren',但结果不一致。

请参阅Plunker2了解其行为方式。

无论如何我可以访问ngFor中的特定组件实例,或者我错过了什么?

版本信息:

Angular:2.4.0;
ng-bootstrap:1.0.0-alpha.20

组件:

@Component({
  selector: 'my-app',
  template: `
    <ngb-tabset (tabChange)="tabChanged($event)">
      <ngb-tab *ngFor="let item of tabs;let tIdx = index;" [title]="item.slice(0,10)">
        <template ngbTabContent>
          <app-grid [content]="item" #grid></app-grid>
        </template>
      </ngb-tab>
    </ngb-tabset>
  `
})

export class App {
  @ViewChild('grid') grid: GridComponent;
  tabs=[
    `Raw denim you probably haven't heard of them jean shorts Austin.`,
      `Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid.`,
      `Mustache cliche tempor, williamsburg carles vegan helvetica.`]
  tabChanged(event){
    debugger;
    console.log(this.grid);
    alert(this.grid.content);
  }
}  

演示

Plunker
Plunker2

1 个答案:

答案 0 :(得分:2)

修改

这些组件是基于模板的,只有在您访问每个选项卡后才会实例化。您可以使用网格组件console.log内的onInit对此进行测试。

因此,从一开始就无法使用它们(实例化主应用程序组件时)。此时仅创建第一个选项卡。

要访问组件实例,您需要确保所有选项卡都以某种方式激活。

您可以使用EventEmitter来跟踪,但是您需要从网格中手动发出事件 - 这可能是一种灵活的方法。您可以发出内容以及组件实例本身

export class GridComponent implements OnInit { 
 @Input() content:string;
 @Output() contentChanged = new EventEmitter<string>();

 ngOnInit(){
  setInterval(() => {
    this.content = this.content + ' xxx ';
    this.contentChanged.emit({ content: this.content, controller: this });
  }, 2000);
}

然后分配一个事件处理程序

<template ngbTabContent>
  <app-grid [content]="item" (contentChanged)="changed(tIdx, $event)"></app-grid>
</template>

你可以用它来跟踪

changed(tIdx, { content, controller }) {
  console.log(tIdx + " : " + content);
  console.log(controller);
}

请参阅plnkr.co/edit/c6m3QyDSd0fWpoJUvTh7?p=preview

原始问题

您可以改为使用@ViewChildren,这样您就可以选择多个组件到数组中:

@ViewChildren(GridComponent) grids: QueryList<GridComponent>; // select by component type but you could also use css - using id however is not ok for multiple items

tabChanged(event){
  debugger;
  console.log(this.grids.toArray());
  alert(this.grids.toArray().map(g => g.content));
}

由于你不再使用id来选择组件,你可以删除它

<template ngbTabContent>
  <app-grid [content]="item"></app-grid>
</template>