Angular5 - 如何将ASYNC数据从父组件传递到子组件

时间:2018-05-12 08:47:55

标签: angular angular5 google-cloud-firestore

当我尝试将ASYNC数据从父组件传递到子组件时,我收到了未定义的消息。

由于ASYNC数据,我认为来自父级的数据尚未绑定在OnInit上。

在parent.component.html中:

<my-child [childdata]="parentdata"></my-child>

在parent.component.ts中:

interface SpotBB {
    id: number;
    name: string;
}
...
export class ParentComponent implements OnInit {
  parentdata: Observable<SpotBB[]>;
  ...
  ngOnInit() {
    this.parentdata = this.spotsservice.getSpots();
    // Call a service - Data stored in Firestore
  }

在child.component.html中:

<button (click)="mycheck()">TEST</button>
<div *ngFor="let spot of childdata | async" >    
    {{ spot.id }} --- {{ spot.name }}     <!-- Works fine -->
</div>

在child.component.ts中:

interface SpotBB {
    id: number;
    name: string;
}
...
export class ChildComponent implements OnInit {
  @Input() childdata: Observable<SpotBB[]>;
  copydata: Observable<SpotBB[]>;
  ...
  mycheck() {
    alert(JSON.stringify(this.copydata));   // --> !!! undefined !!!
  }
  ngOnInit() {
    this.copydata = this.childdata;  // COPY DATA NOT WORKING
  }

2 个答案:

答案 0 :(得分:1)

您可以实施多种选择来使其正常运行:

1。使用ngOnChanges监听子组件中的@Input更改:

// child component
export class ChildComponent implements OnInit {
  @Input() childdata;
  ngOnChanges(changes: SimpleChanges) {
    // on loading you can access childdata
    console.log(changes.childdata.currentValue);
  }

2。set的子组件中使用childdata

// child component
export class ChildComponent implements OnInit {
  private _childdata;
  @Input() set childdata(value) {
    this._childdata = value;
  }


  // get method for childdata (for *nfFor in template)
  get childdata() {
    return this._childdata;
  }

3。仅在parentdata可用之后,才使子组件可用(如果可以):

父组件html:

<my-child *ngIf="parentDataLoaded" [childdata]="parentdata"></my-child>

在parent.component.ts中:

interface SpotBB {
  id: number;
  name: string;
}
...
export class ParentComponent implements OnInit {
  parentdata: Observable<SpotBB[]>;
  parentDataLoaded: false;
  ...
  ngOnInit() {
    this.spotsservice.getSpots()
      .subscribe(res => {
         // here is your successful results
         this.parentdata = res;
         this.parentDataLoaded = true;
      });
  }

对于所有选项,我猜想要订阅getSpots,在父组件中收到parentdata并分配给this.parentdata

// parent component
ngOnInit() {
  this.spotsservice.getSpots()
    .subscribe(res => {
      // here is your successful results
      this.parentdata = res;
    });
 }

 // child component html
 // *ngIf needs only if listening for changing
 // of childdata in child component
 <div *ngIf="childdata">
   <div *ngFor="let spot of childdata" >    
    {{ spot.id }} --- {{ spot.name }}     <!-- Works fine -->
   </div>
 </div>

答案 1 :(得分:0)

而不是 @Input() childData@Input() set childData会有效。这将使 childData 在更改时刷新