Angular 2中的跨组件通信

时间:2017-11-08 20:37:16

标签: angular angular-components

在角度2/4中,我想从组件A到组件B获取数据,并且我需要再次将数据从B发送到组件C,我需要显示组件C的结果。任何人都可以指导我简单的例子?

1 个答案:

答案 0 :(得分:0)

我可以看到两种可能的方法,如何从组件到其他组件获取数据。

第一个,当ComponentA具有子ComponentB并且ComponentB具有ComponentC的子元素时,通过HTML传递数据。类似的东西:

ComponentA

    @Component({
      selector: 'comp-a',
      template: `
<!--[inputDataB]="somedata" passing data to componentB -->    
<!--[validateValue]="validateData" getting data from componetB and passing data to componentB -->    
        <comp-b [inputDataB]="somedata" [validateValue]="validateData"> </comp-b>`
    })
    export class ComponentA implements OnInit {
      title = 'app works!';

      somedata: any;
      constructor(private service: MyService) {}

      ngOnInit(): void {
        this.service.getData()
          .subscribe(data => this.somedata = data);
      }

      validateData = (num: number): boolean => {
        return num >= 0;
      }
    }

以componentB:

@Component({
      selector: 'com-b',
      template: `data of loaded in component A {{ inputDataB }}
        <button (click)="processData(4)" )> Do Something</button>
         <span *ngIf="displayCompC"> <com-c [inputDataC]="dataC"></com-c></span>       
      `
    })
    export class ComponentB implements OnInit {

      @Input()
      inputDataB: any;

      @Input()
      validateValue: (value: number) => boolean;
      dataC: number;
      displayCompC: boolean;
      constructor() {}

      ngOnInit(): void {
        this.displayCompC = false;
        // on load you can modify or process data
        this.dataC = this.inputDataB * 2;
      }

      processData = (num: number) => {
        this.displayCompC = this.validateValue(num);
      }
    }

ComonentC

@Component({
  selector: 'com-c',
  template: `data of loaded in component B {{ inputDataC }}
    {{inputDataC}}
  `
})
export class ComponentC implements OnInit {

  @Input()
  inputDataC: number;

  modifydata: number;

  constructor() {}

  ngOnInit(): void {
    // on load you can modify or process data
    this.modifydata = this.inputDataC * 5;
  }
}

猜猜这不是你想要的,因为ComponentA有组件B和C的视图。

第二种方法是创建注入每个组件构造函数的CommonDataMode。 CommonDataMode将通过其他组件共享数据。类似的东西:

    import {Component, OnInit} from '@angular/core';
    import {CommonDataModel} from './CommonDataMode';
    import {MyService} from './MyService';

    @Component({
      selector: 'app-root',
      template: `{{anyData}}`
    })
    export class AppComponent implements OnInit {

      anydata: number;
      constructor(private service: MyService, private commonDataModel: CommonDataModel) {}

      ngOnInit(): void {
        this.service.getData()
          .subscribe(data =>  {
            this.commonDataModel.data = data;
            this.anydata = data;
          });
      }
    }


@Component({
  selector: 'com-b',
  template: `data B {{ inputDataB }}
        double: {{doubleDate}}
  `
})
export class ComponentB implements OnInit {

  inputDataB: any;
  doubleDate: number;

  constructor(private commonDataModel: CommonDataModel) {}

  ngOnInit(): void {
    this.inputDataB = this.commonDataModel.data;
    this.doubleDate = this.commonDataModel.multiplyByTwo();
  }
}


@Component({
  selector: 'com-c',
  template: `data of loaded in component B {{ inputDataC }}
    {{inputDataC}}
  `
})

export class ComponentC implements OnInit {

  inputDataC: number;
  modifydata: number;

  constructor(private commonDataModel: CommonDataModel) {}

  ngOnInit(): void {
    // on load you can modify or process data
    this.modifydata = this.commonDataModel.data;
    this.modifydata = this.commonDataModel.multiplyByNumber(5);
  }
}

现在CommonDataMode

import {Injectable} from "@angular/core";

@Injectable()
export class CommonDataModel {

  data: number;

  multiplyByTwo = (): number => {
    return this.data * 2;
  }

  multiplyByNumber = (num: number): number => {
    return this.data * num;
  }
} 

首先需要加载组件A的节点。如果在组件B或C中刷新页面,则数据不会被定义。

要解决此问题,请在应用启动前为您的根模块提供APP_INITIALIZER并加载数据。