如何从孩子的父母那里访问模板参考变量? [英] How to access template reference variables from parent in a child?
问题描述
我试图让我分别了解Angular2和Typescript.我想做的是从子组件中的按钮(此处为app-header
)打开sidenav.
I am trying to get my head around Angular2 and Typescript respectively. What I want to do is open a sidenav from a button which is in a child component - here app-header
.
我知道我可以用
<button mat-button (click)="sidenav.open()">Open sidenav</button>
,但是仅当我将其放置在父模板中时才有效,因为它引用了模板变量引用sidenav
.但是,正如我所说,我想通过点击孩子的按钮来打开它.
but that would only work if I place this within the parent template as it references the template variable reference sidenav
. However, as I said, I want to open it based on a click on a button of a child.
这是我的布局/应用模板:
This would be my layout/app template:
<mat-sidenav-container>
<mat-sidenav #sidenav>
<!-- sidenav content -->
Here comes the menu ..
</mat-sidenav>
<div>
<app-header>
<!-- Application header -->
</app-header>
</div>
</mat-sidenav-container>
这将是标题模板:
<div>
header for {{title}} works!
<button mat-button (click)="sidenav.open()">Open sidenav</button>
</div>
这当然会失败,因为我无法引用sidenav
-那么如何从子对象内部正确访问sidenav
?
Of course this fails because I cannot reference sidenav
- so how can I access sidenav
from within the child correctly?
还是在Angular2中传递这样的引用是"no no",我实际上应该使用基于事件的触发器或类似的东西吗?
Or is passing on such references a "no no" in Angular2 and I should actually use an event based trigger or something like that?
推荐答案
这是正常的父/子组件通信.您可以这样做的方法是只在子项上公开输出事件:
this is normal parent / child component communication. The way you COULD do this is to just expose an output event on the child:
parent.component.html摘录:
parent.component.html excerpt:
<child-component (openNav)="sidenav.open()"></child-component>
在子级中,您只需将按钮单击绑定即可发出该事件:
and in the child you just bind the button click to emitting that event:
child.component.ts:
child.component.ts:
@Output() openNav = new EventEmitter();
child.component.html:
child.component.html:
<button (click)="openNav.emit()">Open Nav</button>
但是,由于这是一个sidenav,可能需要在很多地方甚至在嵌套的地方进行访问,因此您可能只想解决所有情况下的问题并使用可观察到的共享服务:
HOWEVER, since this is a sidenav that may need to be accessed in a lot of places and maybe even in nested places, you might just want to solve the problem for all situations and use a shared service observable:
side-nav.service.ts:
side-nav.service.ts:
@Injectable()
export class SideNavService {
private openNavSource = new Subject(); // never expose subjects directly
openNav$ = this.openNavSource.asObservable();
openNav = () => this.openNavSource.next();
}
适当提供它,并将其注入父母和孩子使用
provide it appropriately, and inject it into the parent and child for use
parent.component.ts:
parent.component.ts:
@ViewChild('sidenav') sidenav; // get your template reference in the component
constructor(private sideNavService: SideNavService) { }
private sideNavSub;
ngOnInit() {
this.sideNavSub = this.sideNavService.openNav$.subscribe(() => this.sidenav.open());
}
ngOnDestroy() {
this.sideNavSub.unsubscribe(); //clean your subscriptions
}
child.component.ts:
child.component.ts:
constructor(private sideNavService: SideNavService) { }
openNav() {
this.sideNavService.openNav(); // looks repetitive but accessing injectd services in templates is bad practice and will cause pains down the line
}
child.component.html:
child.component.html:
<button (click)="openNav()">Open Nav</button>
然后,您可以将服务注入到任意组件中,并根据需要使用它.
then you can inject the service into any arbitrary component and use it as needed.
这篇关于如何从孩子的父母那里访问模板参考变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!