0
votes

I got this this hierarchy of component. A parent component who got 2 child components. I want the first child component to update a property of the parent component, after that the second child component re render. I got main component with two child components: one with select html input and the second one a table of data, the data is coming from the main component as an input. The idea is when i change the selected value, i want to change the data in the main component so the data table can get the new data from the main component. How can i do that?

In the first child:

@Output() optionSelected = new EventEmitter<string>();

@Input() data;

In the parent:

 @Input() displayOption: string;
 @Output() dataToSelect 

When the displayOption updated , i want the second child re render

3
Please show your code. You need to look into @Input and @Output decorators.Yashwardhan Pauranik
@YashwardhanPauranik Done.Dhia
what you mean by second child please share us your full codeBear Nithi
Why you want to re render the component? Simply changing the inputs of second component won't work for you?emkay

3 Answers

0
votes

If you are using ChangeDetectionStaretgy.OnPush, could be usefull passing observables in your child components, and use async pipe. In this way, child components will be redrawed only on emits by observable:

First Child:

@Output() optionSelected = new EventEmitter<string>();

selectOption() {
  this.optionSelected.emit('firstChild')
}

First Child html:

<button (click)="selectOption()">Select<button>

Second Child:

@Input() data$;

Second Child.html:

<p>{{data$ | async}}</p>

Parent:

data = new BehaviorSubject('')
setSelectedOption(val) {
  this.data.next(val)
}

Parent.html:

<first-child (optionSelected)="setSelectedOption($event)"></first-child>
<second-child [data$]=""></second-child>
0
votes

@Output decorators is used to share data between child to parent component. EventEmitter is used to emit the values.

child.component.ts

@Output() optionSelected = new EventEmitter<string>();

sendDataToChild() {
  this.optionSelected.emit('hello');
}

parent.component.html

In child component's selector you can listen for the event using (optionSelected), when the event gets emitted log() method in parent components gets invoked.

<child-comp (optionSelected)="log($event)"></child-comp>

parent.component.ts

log(value) {
   console.log(value);
}
0
votes

To re-render a component dynamically you can use ComponentFactoryResolver as follows:

In your HTML template you need an 'anchor' for the new component:

<ng-template #child2></ng-template>

In your parent-component.ts you will need to reference the anchor by ViewChild and you will need to inject the ComponentFactoryResolver:

constructor(private cfr: ComponentFactoryResolver) { }

@ViewChild('child2', { read: ViewContainerRef }) childHost: ViewContainerRef;

renderChild2(data ?: any) { // im making this optional because i dont know if you require any data to init the component
    this.childHost.clear(); // clear the current rendered component inside the anchor (if any)
    const factory = this.cfr.resolveComponentFactory(<YOUR COMPONENT NAME>);
    const componentReference = this.childHost.createComponent(factory);
    if (data) {
        componentReference.instance.data = data; // you can access any public property/method in your component via instance
    }
}

All you have to do is call the renderChild2() fcn whenever you want to re-render you child2 component.