Angular 2 - Passing data to Child component after Parent initialisation

痞子三分冷 提交于 2019-12-02 17:29:01

Since data is undefined at start, you can postpone it with *ngIf='data'

<div *ngIf='data'>
   <test-child [childData]="data"></test-child>
</div>

Or you can implement ControlValueAccessor on your component and pass it by ngModel with ngModelChange

<test-child [ngModel]="data?" (ngModelChange)="data? ? data= $event : null"></test-child>

you can use ngOnChanges to get data like below,

 ngOnChanges() {
   if(!!childData){         
        console.log(childData);         
   }
 }

OnChanges

Angular calls its ngOnChanges method whenever it detects changes to input properties of the component (or directive).

Read more about it here.

Update

ngOnChanges will only fire if you change entire object, if you want to just update property of the bound object not entire object you have two options,

  1. either bind the property directly in the template, make sure to use ? like {{childData?.propertyname}}

  2. or you can create a get property depending upon childdata object,

    get prop2(){
      return this.childData.prop2;
    }
    

Copmlete Example,

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

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
  <child-component [childData]='childData' ></child-component>
  `
})
export class AppComponent { 
  name = 'Angular'; 
  childData = {};
  constructor(){
    // set childdata after 2 second
    setTimeout(() => {
      this.childData = {
        prop1 : 'value of prop1',
        prop2 : 'value of prop2'
      }
    }, 2000)
  }
}

@Component({
  selector: 'child-component',
  template: `
    prop1 : {{childData?.prop1}}
    <br />
    prop2 : {{prop2}}
  `
})
export class ChildComponent { 
  @Input() childData: {prop1: string, prop2: string};

  get prop2(){
    return this.childData.prop2;
  }
}

Here is the Plunker!

Hope this helps!!

At the time your ChildComponent (you called it also ParentComponent, but i guess it's a typo) gets initialized and executes its ngOnInit, there is no data in your parent avaible since your service will still be out getting your data. Once your data is there it will be pushed to the child.

What you can do depends on your usecase..

If you just want to display the data in your ChildComponent template, you could use the elvis operator (?). Something like: {{ childData?}} or {{ childData?.myKeyName }}...

If you want to do some other stuff, you may use a setter in your ChildComponent. It will intercept the input change and give you the opportunity to alter/test/"do what ever you want" with it before you do other things with it in your ChildComponent.. eg.:

@Component({
    selector: 'test-child',
    template: `
        <!-- Content for child.... -->
    `
})

export class ChildComponent implements OnInit {
    private _childData: any;
    @Input()
    set childData(parentData: any) {
        // every time the data from the parent changes this will run
        console.log(parnetData);
        this._childData = parentData; // ...or do some other crazy stuff
    }
    get childData(): any { return this._childData; }

    ngOnInit() {
      // We don't need it for that...
    }
}

or use ngOnChanges as Madhu mentioned.

You also might want to take a look at the cookbook entry for Component Communication in the official docs.



   `@Component({
    selector: 'test-child',
    template: `
        
    `
})

export class ChildComponent implements OnChanges {
    @Input() childData: any;

    ngOnChanges() {
        console.log(childData); // logs undefined
    }
}`

This is supposed to be like this no?I hope this might be the problem


`ngOnChanges() { console.log(this.childData); // reference with this

}`

I'm assuming that the child is getting a subset of the parents data, potentially from a user action (like loading a form when a user clicks on a grid row). In this case I would use an event.

Have the parent fire an event, maybe dataSelected, and the contents of the event would be the data that was selected.

Then have the child listen for those events and when fired load the data from the event into the model.

This will help decouple your components, which always a good idea.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!