如何通知另一个组件该方法执行

时间:2017-08-24 13:10:38

标签: javascript html angular typescript

我有四个组件,父组件componets.html看起来像

<div class="main">
    <div class="column-left">
        <app-document-info></app-document-info>
    </div>
    <div class="column-center" style="float:left">
        <app-document-scan></app-document-scan>
    </div>
</div>

Document-Scan组件还包含其中的组件,该组件的一些片段代码(Document-Nested)

<div class="btnGrp">
  <input type="file" name="img" multiple (change)="onChange($event)">
</div>

  public onChange(event: Event) {
    this.loadFiles();
  };

  loadFiles() {
    let files = event.target['files'];
    this.allFiles = files.length;

    for (var i = 0; i < files.length; i++) {
      let fileReader = new FileReader();
      fileReader.onload = () => {
        let infoFile: string = fileReader.result;
        let obj: fileStructure = {
          name: files[this.loadedFiles].name,
          data: fileReader.result,
          type: files[this.loadedFiles].type
        }
        this.listImages.push(obj);
        this.loadedFiles++;
        this.loadImage();
      }
      if (fileReader && files && files.length) {
        fileReader.readAsDataURL(files[i]);
      }
    }
  }

 loadImage() {
      this.imageService.setImages(this.listImages);
      this.imageLoadedEvent.emit(this.isClickedFileUploader);
}

我的组件Document-info我有一些方法可以执行 文档扫描的方法loadFiles()已完成或将数据传递给我使用服务注入loadImage()方法的组件

这是我的服务

    export class ImageService {
    isClicked: boolean = false;    
    listImages: fileStructure[] = [];
    bodyContent;

    setBodyRes(res) {
        this.bodyContent = res;
    }

    getBodyRes() {
        return this.bodyContent;
    }

    setImages(imageList: fileStructure[]) {
        this.listImages = imageList;
    } 

    getImages(): fileStructure[] {
        return this.listImages;
    }
}

如何传递数据或通知在Document-Scan内部的组件Document-Nested之间完成执行的某些方法 和文档信息。 Document-Scan和Document-Info是兄弟姐妹?

3 个答案:

答案 0 :(得分:3)

您可以使用多种不同的方法在组件之间进行通信,您可以在此处找到更多信息:https://angular.io/guide/component-interaction

在您的情况下,您可能希望文档扫描公开事件:

@Output() onLoadFilesCompleted = new EventEmitter<DataType>();

然后,父母需要像这样订阅它

<app-document-scan [onLoadFilesCompleted]="doSomething()"></app-document-scan>

您还可以使用注入服务,允许在许多不同组件之间进行通信,如果事情变得复杂,这可能会更容易。

答案 1 :(得分:2)

使用@Output装饰器。您还没有为您的组件发布代码,因此我将假设名称:

<app-document-scan>组件中:

import { Output, EventEmitter } from '@angular/core';
...
export class DocumentScanComponent {
    @Output() filesLoaded: EventEmitter<boolean> = new EventEmitter();

    loadFiles() {
        let files = event.target['files'];
        this.allFiles = files.length;

        for (var i = 0; i < files.length; i++) {
          let fileReader = new FileReader();
          fileReader.onload = () => {
            let infoFile: string = fileReader.result;
            let obj: fileStructure = {
              name: files[this.loadedFiles].name,
              data: fileReader.result,
              type: files[this.loadedFiles].type
            }
            this.listImages.push(obj);
            this.loadedFiles++;
            this.loadImage();

            // Emit the event here
            this.filesLoaded.emit(true);
          }
          if (fileReader && files && files.length) {
            fileReader.readAsDataURL(files[i]);
          }
        }
      }
}

将您的父母componets.html更改为以下内容:

<div class="main">
    <div class="column-left">
        <app-document-info #documentInfo (filesLoaded)="onFilesLoaded()"></app-document-info>
    </div>
    <div class="column-center" style="float:left">
        <app-document-scan></app-document-scan>
    </div>
</div>

..并在你父母的components.ts中定义方法:

import {Component,ViewChild} from '@angular/core';

@Component({
    ....
})
export class ParentComponent {
    @ViewChild('documentInfo) documentInfo: DocumentInfoComponent;

    onFilesLoaded(){
        documentInfo.someMethodYouWantToCall();
    }
}

答案 2 :(得分:1)

您可以使用@Input实现此目的。

父组件可以告诉孩子加载了哪些文件(@Input of child)。

使用@Ouput,您可以告诉父母您完成或传回文件。

在此之后,父母可以使用所有文件为您的第二个孩子做另一个@Input。

阅读https://angular.io/guide/component-interaction