I have a component inside another component, added by tag. At some point, i would like to reinitialize this sub-component, like the first it was invoke. Is there any way to do that?
-
1What are you trying to do? There is no way to just tell a component to reinitialize itself. But there are ways to get it to reget new data for itself. If you could provide a bit more information, we can suggest some options for you.DeborahK– DeborahK2017-08-01 16:19:48 +00:00Commented Aug 1, 2017 at 16:19
-
The idea is to open the component as a modal, pre-loaded in each component that will open it. Of course, when the modal is closed, the component needs to be reinitilized for future calls.jonyjm– jonyjm2017-08-01 16:46:12 +00:00Commented Aug 1, 2017 at 16:46
7 Answers
You can write your own cleanup method. But faster way (but not trully convenient) is to use *ngIf. When value is false, component is completely removed (destroyed) from page. When it is back to true it goes via regular path constructor > ngOnInit, etc. Why it is not convenient?
- it may look ugly
- it may require from you to trigger change detection manually
.
reinitChildComponent(): void{
this.childVisible = false;
this.changeDetectorRef.detectChanges();
this.childVisible = true;
this.changeDetectorRef.detectChanges();
}
2 Comments
You can re initialize component using *ngIf.
<mychild *ngIf="flag"></mychild>
You can re initialize by making the flag false and true.
1 Comment
ChangeDetectorRef to trigger detection of the toggling without setTimeout e.g. this.flag = false; this.cd.detectChanges(); this.flag = true;.Add a public method in your child component say init (). Then add an id to your child component in your parent component html.
<my-child #myChild></my-child>
Then you can get the child component like:
@ViewChild('myChild') private myChild: MyChildComponent;
From that you can call the init() method which has all initialization logic of component.
4 Comments
I ran into this problem when doing a test page that would render components for visual inspection.
I tried the ngIf approach mentioned in another answer, but it didn't work without using a setTimeout which seems more like a hack.
Turns out that ngFor is perfect for this. You just use an array with a single empty object. Each time you modify the array then ngFor will re-create the inner component.
public reset: any[] = [{}];
public onRecreate() {
this.reset[0] = {};
}
Then in your template
<my-child-component *ngFor="let r of reset"></my-child-component>
<button (click)="onRecreate()">Reset</button>
2 Comments
Usually you should just move the child-component's initializing logic from it's constructor / ngOnInit into it's ngOnChanges hook. But if you really need to re-initialize a component due to whatever reasons (usually if the represented object has changed), just use an *ngFor, which iterates over an array with only that specific reason as element:
<child-component [child]="child" *ngFor="let child of [child]"></child-component>
You can use a trackBy Function, if you want the component to re-initialize only if a certain property of the represented object has changed.
Comments
usually the best practice, in this case, is to create Behovire Subject and pass it to the component as @input()
then you can fire any action by calling behoviresubjects.next('hi')
ex:
in your parent component
import { BehaviorSubject } from 'rxjs';
brodCastChnage: BehaviorSubject<any> = new BehaviorSubject(null);
and when you need to notify the child component about something :
this.brodCastChnage.next('something');
in HTML of the parent as well
<my-child [onChange]="brodCastChnage"></my-child>
in child component
@Input() onChange;
ngOnInit() {
this.onChange.subscribe(res=>{
console.log('i received',res)
});
}
- don't forget to unsubscribe on destroy
3 Comments
Here is a good example, how to call child component from parent component:
I call child component's function in to my parent component like this:
<cp-file-manager [(ngModel)]="container" name="fileManager"[disableFiles]="true" [disableDocId]="id" [newFolderId]="newFolderId"></cp-file-manager>
Here you can see how to call child component function from parent component ts file:
import { Component, OnInit, ViewChild } from '@angular/core';
import { FileManagerComponent } from '../../../../shared/components/file-manager/file-manager.component'
@ViewChild(FileManagerComponent) fileManager: FileManagerComponent;
doSomething() { //this is parent component function
this.fileManager.openFolder(); //openFolder-is child component function
}
additional info: http://learnangular2.com/viewChild/