I have a side navigation component to be used on many pages. This is not a single-page web app. It is dynamically loaded on a parent component that toggles the menu. ContentChild is used to get a handle on the child component so that it can be toggled by setting @input overlayHidden. The problem is that ContentChild is null.
Run this plunker with the debug console open. Click "Dashboard" from the first page, and then "Toggle Menu" from the second page to see the null pointer.
What am I doing wrong?
Here is the code.
import { Component, Input} from 'angular2/core';
import { Router } from 'angular2/router';
@Component({
selector: 'side-navigation',
template: `
<div id="overlay" [hidden]="overlayHidden">
<div id="wrapper">
<nav id="menu" class="white-bg active" role="navigation">
<ul>
<li><a href="#">Dashboard</a></li>
<li><a href="#">Help & FAQs</a></li>
<li><a href="#">Contact Us</a></li>
<li><a href="#">Log Out</a></li>
</ul>
</nav>
</div>
</div>
`
})
export class SideNavigationComponent {
@Input() overlayHidden: boolean;
}
import { Component,
DynamicComponentLoader,
Injector,
ContentChild, AfterContentInit
} from 'angular2/core';
import { Router, RouterLink } from 'angular2/router';
import { SideNavigationComponent } from './side-navigation';
@Component({
selector: 'dashboard',
template: `
<side-navigation id="side-navigation"></side-navigation>...
`,
directives: [
RouterLink,
SideNavigationComponent ]
})
export class DashboardComponent {
title = 'Dashboard';
@ContentChild(SideNavigationComponent)
sideNavigationComponent: SideNavigationComponent;
constructor(private _router: Router,
private _dcl: DynamicComponentLoader,
private _injector: Injector) {
this._router = _router;
this._dcl = _dcl;
this._injector = _injector;
this._dcl.loadAsRoot(
SideNavigationComponent,
'#side-navigation', this._injector);
}
toggleOverlay() {
this.overlayHidden = !this.overlayHidden;
this.sideNavigationComponent.overlayHidden = this.overlayHidden;
}
}
I built a publish/subscribe solution that works (except for an issue with the 'hidden' attribute of the overlay div), but I thought this would be a simpler solution if I could get it to work.