我的子组件如何在Angular 2中的父组件上调用方法?
假设我有一些父组件,称为MatchList
,它提供了Hero
对象的列表以及其他内容.每个Hero
对象都具有某些表中显示的属性.现在,假设每个Hero
都有一个按钮,用于更新路线,加载新视图并显示更多详细信息.
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.
之前
之后
问题
我的基本问题是:我想从我的MatchList
模板中的按钮调用路由器的navigate()
方法,但是当我尝试这样做时会收到以下错误:
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:
例外:评估"click"时出错:BrowserDomAdapter.logError @ ... angular2.dev.js:21835原始异常:TypeError:l_context.setPath不是函数... angular2.dev.js:21835 TypeError:l_context.setPath不是...的函数...
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.
那么,Angular 2中子组件访问父组件(或上下文")方法的正确和最佳方法是什么?
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.
到目前为止我的摘要.
//父母
@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);
}
}
}
//孩子
@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')
);
}
}
//模板
<table class="table">
...
<button (click)="setPath(match.match_id)">Match Detail Route</button>
</table>
在这个问题的上下文中,即调用父级router
,答案很简单.有关详细信息,请参见此矮人.
In the context of this question, namely calling a parent router
, the answer, it turns out, is trivial. See this plunker for details.
主要收获是给子组件一个路由器la
The main takeaway is that giving a router to a child component a la
class ChildComponent {
constructor(router: Router) {
...
}
}
不会不创建新的路由器,它只是扩展了父组件的现有路由器.因此,消除了对父对象的引用的需要.只需调用childRouter的方法,一切都会按预期进行.
does not create a new router, it merely extends the existing router of the parent component. Thus, the need to a reference to the parent object is obviated. Just call the methods of the childRouter and everything works as expected.