如何从孩子的父母那里访问模板参考变量? [英] How to access template reference variables from parent in a child?

查看:87
本文介绍了如何从孩子的父母那里访问模板参考变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我分别了解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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆