Angular 如何从父组件调用路由器出口子组件方法
我是安格拉尔的新手Angular 如何从父组件调用路由器出口子组件方法,angular,typescript,angular2-routing,Angular,Typescript,Angular2 Routing,我是安格拉尔的新手 <parent> <router-outlet><router-outlet> </parent> 我在父组件中有一个按钮,如果我单击该按钮,它将调用子组件中的一个方法(加载到路由器出口中) 有什么方法可以从父组件调用子组件(在路由器出口中)方法吗?显示组件模板基本上有两种方法:作为嵌套组件或作为路由目标 嵌套组件 onActivate(componentRef){ componentRef.works
<parent>
<router-outlet><router-outlet>
</parent>
我在父组件中有一个按钮,如果我单击该按钮,它将调用子组件中的一个方法(加载到路由器出口中)
有什么方法可以从父组件调用子组件(在路由器出口中)方法吗?显示组件模板基本上有两种方法:作为嵌套组件或作为路由目标 嵌套组件
onActivate(componentRef){
componentRef.works();
}
如果使用嵌套组件,则这些组件将被视为具有“父组件/子组件”关系
父组件的Html将如下所示:
<div>
<child></child>
</div>
其中“child”是子组件的选择器。然后,您可以使用@Input和@Output属性在两者之间进行通信
当您有嵌套组件时,有关此技术的更多信息,请查看此处的文档:
路由目标
onActivate(componentRef){
componentRef.works();
}
如果通过在
中显示组件来将其用作路由目标,则不存在“父组件”和“子组件”关系
在这种情况下,组件之间通信的最佳方式是使用服务
我在这里有一篇关于创建服务的博文:
资源
如果你对Angular还不熟悉,你可以通过辅导或在线课程为自己节省大量时间和挫折。这将介绍所有的基本概念,让你在你的方式与角度快速
您可以在此处学习“英雄之旅”教程:
或者观看这样的课程:
或者这个:
(你可以免费注册一周。)我找到了两种方法来实现这一点: 1。将主要成分注射到儿童体内 您可以向主组件添加事件,将主组件注入子组件并订阅事件。请参见说明这一点的示例。但是,现在您的孩子依赖于您的主要组件。这可能不好 主要成分 2。实施服务
<router-outlet (activate)="onActivate($event)"></router-outlet>
此处以及中所述的最佳解决方案是创建一个服务,该服务将成为主组件和子组件之间的附加层。这样,您将独立于主组件实现。请参见说明此方法的
服务
主要成分
孩子
使用
路由器出口中的child
,您可以使用ContentChild
来调用child中的方法。所以
import { ContentChild } from '@angular/core';
在您的家长中:
@ContentChild(ChildComponent)
private childComponent: ChildComponent;
在您的点击事件中,请执行以下操作:
this.childComponent.doSomething()
此外,您还需要在父级中的providers数组中添加子组件:
@Component({
selector: 'parent',
...
providers: [ChildComponent]
})
我想我可以帮你
虽然您也可以在子组件中直接使用它,但在这里使用公共服务将是一个很好的实践
首先,您需要在服务中创建发射器,例如
export class EmitterService {
public nameEmitter:EventEmitter<string>=new EventEmitter();
//method to get question
changeName(name:string){
this.nameEmitter.emit(name)
}
}
最后在子组件中订阅更改
this.emitter.nameEmitter.subscribe(name=>{this.name=name})
这里正在工作您可以使用与路由器添加的组件通信
您还可以使用路由器出口的名称让父级知道路由器何时添加组件
模板
<router-outlet (activate)="onActivate($event)"></router-outlet>
儿童薪酬
works(){
console.log("works");
}
有两种方法可以从父组件调用router outlet子组件方法
this.childComponent.changeTitle();
在我搜索了很多关于这个问题的信息后,我找到了一个解决方案,希望它能对您有所帮助。 contentChild/ViewChild无法访问路由器出口中加载的组件(及其数据),使用sharedService需要额外的文件和更多代码 您只需读取路由器出口中加载的组件:
<router-outlet #myRouterOutlet ></router-outlet>
@ViewChild("myRouterOutlet", { static: true }) routerOutlet: RouterOutlet;
buttonClicked(){
const childComp = this.routerOutlet.component as childComponent;
childComp.childFunction();
}
希望能对你有所帮助:)虽然这是一个老问题,但这里的回答并不完美 通过使用服务或子实例,您可以将自己绑定到特定的函数 您需要调用的名称。服务还强制您使用依赖项注入 有一个更好的方法,使用一个指令,使每一方完全独立 从另一个
指令是。这也可以通过以下方式实现: .html
在10年内,上述解决方案对我都不起作用。让我与您分享我为管理此问题而创建的CustomEventHandler服务:
@Injectable()
export class CustomEventHandler {
private eventHandlersMap: Map<string, Function> = new Map();
constructor() {
}
public callEvent(eventName: string, data?: any): void {
this.eventHandlersMap.get(eventName)(data);
}
public addListener(eventName: string, callback: Function): void {
this.eventHandlersMap.set(eventName, callback);
}
}
在示例代码中,
应该是带破折号的
。如果我错了,请纠正我,ContentChild是预定义的,Childcomponent是用户定义的。我尝试过,但我无法从undefinedAaah调用methodXXx,我知道我忘记了一些东西:P您需要在父级的providers数组中添加子级(无需将其注入构造函数),编辑了我的答案:)它现在应该可以工作了。你在评论中的假设是正确的。最后一个问题,。它完美地调用了child方法,但在child方法中。我需要重新分配一个变量。我看不到基于新任务的UI呈现。你能建议一下吗?这还不够。你能用我制作的插件来展示这个问题吗?我已经创建了,plnkr.co/edit/e7HdIv9Mqeky00nHADvJ?p=预览第一次单击加载子项,然后将子项加载到routeroutlet中。现在单击更改名称按钮。我
this.childComponent.changeTitle();
<router-outlet #myRouterOutlet ></router-outlet>
import {...
RouterOutlet,
..} from "@angular/router";
@ViewChild("myRouterOutlet", { static: true }) routerOutlet: RouterOutlet;
buttonClicked(){
const childComp = this.routerOutlet.component as childComponent;
childComp.childFunction();
}
<parent>
<router-outlet (activate)="onActivate($event)"><router-outlet>
</parent>
activatedComponentReference:any
onActivate(activatedComponentReference) {
this.activatedComponentReference = activatedComponentReference;
}
onBtnClick() {
const childRouteComp = this.activatedComponentReference as ChildRouteComponent;
childRouteComp.childFunction();
}
@Injectable()
export class CustomEventHandler {
private eventHandlersMap: Map<string, Function> = new Map();
constructor() {
}
public callEvent(eventName: string, data?: any): void {
this.eventHandlersMap.get(eventName)(data);
}
public addListener(eventName: string, callback: Function): void {
this.eventHandlersMap.set(eventName, callback);
}
}
// add listener in child component
this.customEventHandler.addListener("some-event", this.someMethodToCall.bind(this));
// call this in parent component
this.customEventHandler.callEvent("some-event");