Reputation: 15
I have app component with two child comoponent, namely first and second and I'm navigating through router outlet tag. I want to change parent component variable to 'XYZ' when I click on child component button.
app.component.html
<a routerLink = "/first">
First
</a>
<a routerLink = "/second">
Second
</a>
<div>
<router-outlet></router-outlet>
</div>
{{myvar}}
app.component.ts
export class AppComponent {
title = 'childParentInteraction';
myvar : String = "ABCD";
}
app-routing.module.ts
const routes: Routes = [
{
path:"first", component: FirstComponent
},
{
path:"second",component: SecondComponent
}
];
first.component.html
<div>
<p>first works!</p>
<button (click)="changeVar()">
Change variable
</button>
</div>
first.component.ts
export class FirstComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
changeVar(){
}
}
Upvotes: 1
Views: 1396
Reputation: 1085
For this story:
You should create a service which holds your variable.
my-var.service.ts
@Injectable({providedIn: 'root'})
export class MyVarService {
private myVar$ = new BehaviorSubject<any>(null);
myVar: Observable<any> = this.myVar$.asObservable();
setMyVar(newValue: any) {
this.myVar$.next(newValue);
}
}
FirstComponent: You need to inject and use setMyVar method of your service.
fist.component.ts
export class FirstComponent {
constructor(private myVarService: MyVarService) {}
setValue(value: any) {
this.myVarService.setMyVar(value);
}
}
AppComponent: You need to listen observable of myVar
app.component.ts
export class AppComponent implements OnInit, OnDestroy {
myVar: any;
destroyer$: Subject<void> = new Subject();
constructor(private myVarService: MyVarService) {}
ngOnInit() {
this.myVarService.myVar.pipe(takeUntil(this.destroyer$)).subscribe(myVar => this.myVar = myVar);
}
ngOnDestroy() {
this.destroyer$.next();
this.destroyer$.complete();
}
}
Upvotes: 1
Reputation: 1870
you probably want an eventEmitter:
<router-outlet (messageEvent)="buttonClicked($event)"></router-outlet>
then on the child ts file:
add Output and EventEmitter to your import statement.
add an @Output statement
then add this.messageEvent.emit('pressed');
Upvotes: 0
Reputation: 774
Welcome to Stack Overflow!
There is a trick you can use in Angular 6:
By injecting the ViewContainerRef on children components:
constructor(private viewContainerRef: ViewContainerRef) { }
And than you can access like this:
getParentComponent() {
return this.viewContainerRef[ '_data' ].componentView.component.viewContainerRef[
'_view' ].component
}
this.getParentComponent().myvar = "XYZ"
Upvotes: 0