如何在angular2中使用视图子项

时间:2017-05-03 10:47:04

标签: angular

我有一个这样的HTML代码,其中包含app-image-upload-component

的模板引用变量
<div *ngFor="let image of images"; let i = index>
  <app-image-upload #imageUpload (click)="uploadImage(i)" (image)="setImageData($event, i)">
    <img src="assets/img/camera-img.png" alt="img">
    <h4>Upload Image</h4>
  </app-image-upload>
</div>

然后在我的打字稿代码中,我正在做这样的事情

@ViewChild('imageUpload') imageUpload: ImageUploadComponent;

uploadImage(index) {
  console.log('index', index);
  this.imageUpload.showImageBrowseDlg();
}

当我触发click event on app-image-upload时,无论index value 0的索引是什么,它始终会显示*ngFor

我知道这种情况正在发生,因为#imageUpload仅仅是ngFor的第一个元素,所以有没有办法以不同的方式引用*ngFor的所有元素并使用它们,如在我的代码中需要。

3 个答案:

答案 0 :(得分:1)

您可以使用ViewChildren组件的QueryList

{{1}}

答案 1 :(得分:1)

最后我想出了如何解决这个问题,而不是@ViewChild,我可以使用@ViewChildren并可以做这样的事情。

@ViewChildren(ImageUploadComponent) imageUploadChildren: QueryList<ImageUploadComponent>;

#Subscribe for changes, so that if we delete any children, then it must new array.

ngAfterViewInit() {
  this.imageUploadChildrenArray = this.imageUploadChildren.toArray();
  this.imageUploadChildren.changes.subscribe(childern => {
  this.imageUploadChildrenArray = childern.toArray();
});

}

uploadImage(index) {
  this.imageUploadChildrenArray[index].showImageBrowseDlg();
}

答案 2 :(得分:0)

您可以传递#ref来处理函数。确保您使用exportAs导出upload指令并为其指定ref。请看这里的例子:

https://plnkr.co/edit/BN2dreniteQag82h28BC?p=preview

  @Directive({
    selector: '[upload]',
    exportAs: 'upload'
  })
  export class Upload {
    static i =0;
    constructor() {
      this.instanceI = Upload.i++;
      console.log('upload');
    }
  }

  @Component({
    selector: 'my-app',
    template: `
      Last handled upload {{last}}
      <div *ngFor="let i of items">
        <h2 upload #uploadRef="upload" (click)="handle(uploadRef)">Hello {{i}}</h2>
      </div>
    `,
  })
  export class App {
    items = ['a', 'b', 'c'];

    constructor() {
    }

    handle(uploadRef) {
      console.log(uploadRef);
      this.last = uploadRef.instanceI;
    }
  }