Background
Suppose I have some parent component, call it MatchList, that presents a list of Hero objects, among other things. Each Hero object has properties that are shown in some table. Now suppose I also have a button for each Hero that updates the route, loads a new view, and shows more details.
Before
After
Problem
My problem essential is this: I want to call the router's navigate() method from a button in my MatchList template, but I receive the following error when I attempt to do so:
EXCEPTION: Error during evaluation of "click"BrowserDomAdapter.logError @ ... angular2.dev.js:21835 ORIGINAL EXCEPTION: TypeError: l_context.setPath is not a function... angular2.dev.js:21835 TypeError: l_context.setPath is not a function at ...
In other words It looks like I cannot reference the parent component's router methods in the child template.
So, what is the correct and best way in Angular 2 for a child component access the methods of the parent component ( or 'context')?
I'd prefer if the solution was something cleaner than
class parent {
child: Child;
constructor(...) {
...
this.child.parent = this;
}
}
Sample Code
EDIT I changed my template button to
(^click)="setPath(match.match_id)"
I am not longer receiving an error message, but nothing happens - I don't even get a console log confirming the click.
Snippets of what I have so far.
//Parent
@Component({
selector: 'dota-app',
directives: [Home, MatchesView, ROUTER_DIRECTIVES],
templateUrl: 'AppView.html'
})
@RouteConfig([
{ path: '/', component: Home, as: 'Home' },
{ path: '/matches', component: MatchesView, as: 'Matches' },
{ path: '/match-details', component: MatchDetailsView, as: 'MatchDetails'}
])
export class RootDotaComponent {
router: Router;
constructor(router: Router) {
this.router = router;
}
public setPath(linkParams: any[]|string): void {
if (typeof linkParams === "string")
linkParams = [linkParams];
this.router.navigate(<any[]>linkParams);
}
}
}
//Child
@Component({
selector: 'matches-view',
providers: [DotaRestDao],
})
@View({
templateUrl: './components/MatchesView/MatchesView.html',
directives: [CORE_DIRECTIVES]
})
export class MatchesView {
public result;
private dataService: DotaRestDao;
constructor(dataService: DotaRestDao) {
this.result = { matches: [] };
this.dataService = dataService;
this.dataService.getData({
baseUrl: DotaRestDao.MATCH_HISTORY_BASE
}).subscribe(
res => this.result = res.result,
err => console.log("something wrongable", err),
() => console.log('completed')
);
}
}
//Template
<table class="table">
...
<button (click)="setPath(match.match_id)">Match Detail Route</button>
</table>
(^click)="setPath(match.match_id)", notice the carat. Did you have something else in mind? Not sure if I'm up to speed on events.<matches-view (selectHero)="changeRouteToHero($event)">, then generate the selectHero event from your component to let the parent handle it and change the route with the changeRouteToHero method.