I have 2 components one is a Topbar and the second is a Display here they are:
Display:
import {Component, View, NgIf} from 'angular2/angular2';
import {Topbar} from '../topbar/topbar';
@Component({
selector: 'display'
})
@View({
templateUrl: './components/display/display.html',
styleUrls: ['./components/display/display.css'],
directives: [Topbar, NgIf]
})
export class Display {
showGrid: boolean;
constructor(){
this.showGrid = true;
}
}
Display HTML(important for my issue):
<topbar></topbar>
<div *ng-if="showGrid" class="display-list">
<h1>true</h1>
</div>
<div *ng-if="showGrid == false" class="display-list">
<h1>false</h1>
</div>
As you can see I have an if statement depending on the showGrid property. Now here is my Topbar component:
Topbar:
import {Component, View} from 'angular2/angular2';
import {ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: 'topbar'
})
@View({
templateUrl: './components/topbar/topbar.html',
styleUrls: ['./components/topbar/topbar.css'],
directives: [ROUTER_DIRECTIVES]
})
export class Topbar {
toggleGrid(){
// update Display showGrid property
}
}
Topbar HTML:
<div (click)="toggleGrid()" class="col-md-1 no-padding grid-toggle">
<img src="assets/imgs/icons/icon-list.svg">
</div>
As you can see I have a function toggleGrid this function is to toggle the Display property showGrid; however, I can't seem to find a way to get this done. Since Topbar is a directive of Display I can't inject Display into Topbar. I've tried creating a service but the issue with this is that it doesn't update the Display showGrid property
There is two approaches:
1.
You just need to define some toggle-grid event (output property) for your <toolbar> component and then listen to it in your Display component. See this plunker.
@Component({
selector: 'topbar'
})
@View({
template: `
<div (click)="onButtonClick()">
Button
</div>
`
})
export class Topbar {
@Output() toggleGrid = new EventEmitter();
onButtonClick() {
this.toggleGrid.next();
}
}
@Component({
selector: 'display'
})
@View({
directives: [Topbar, NgIf],
template: `
<topbar (toggle-grid)="toggleGrid()"></topbar>
<div *ng-if="showGrid" class="display-list">
<h1>true</h1>
</div>
<div *ng-if="showGrid == false" class="display-list">
<h1>false</h1>
</div>
`
})
export class Display {
showGrid: boolean = true;
toggleGrid() {
this.showGrid = !this.showGrid;
}
}
2.
Use @Host and maybe forwardRef to inject parent component into child. See this plunker
@Component({
selector: 'topbar'
})
@View({
template: `
<div (click)="onButtonClick()">
Button
</div>
`
})
export class Topbar {
display: Display;
constructor(@Host() @Inject(forwardRef(() => Display)) display: Display) {
this.display = display;
}
onButtonClick() {
this.display.toggleGrid()
}
}
@Component({
selector: 'display'
})
@View({
directives: [Topbar, NgIf],
template: `
<topbar></topbar>
<div *ng-if="showGrid" class="display-list">
<h1>true</h1>
</div>
<div *ng-if="showGrid == false" class="display-list">
<h1>false</h1>
</div>
`
})
export class Display {
showGrid: boolean = true;
toggleGrid() {
this.showGrid = !this.showGrid;
}
}
Personally, I much prefer the first approach as it makes data flow of your application to be more explicit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With