如何从孩子的父母访问模板引用变量?
Posted
技术标签:
【中文标题】如何从孩子的父母访问模板引用变量?【英文标题】:How to access template reference variables from parent in a child? 【发布时间】:2018-04-07 01:41:48 【问题描述】:我正试图分别了解 Angular2 和 Typescript。我想要做的是从子组件中的按钮打开一个sidenav - 这里是app-header
。
我知道我可以打开它
<button mat-button (click)="sidenav.open()">Open sidenav</button>
但这只有在我将它放在父模板中时才有效,因为它引用了模板变量引用sidenav
。但是,正如我所说,我想通过点击一个孩子的按钮来打开它。
这将是我的布局/应用程序模板:
<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
?
或者在 Angular2 中传递这样的引用是“不”,我实际上应该使用基于事件的触发器或类似的东西?
【问题讨论】:
sidenav 变量到底指的是什么?你能告诉我们那个代码吗? 【参考方案1】:这是正常的父/子组件通信。您可以这样做的方法是只在孩子上公开一个输出事件:
parent.component.html 摘录:
<child-component (openNav)="sidenav.open()"></child-component>
在孩子中,您只需将按钮单击绑定到发出该事件:
child.component.ts:
@Output() openNav = new EventEmitter();
child.component.html:
<button (click)="openNav.emit()">Open Nav</button>
但是,由于这是一个可能需要在很多地方甚至嵌套的地方访问的 sidenav,您可能只想解决所有情况的问题并使用可观察的共享服务:
side-nav.service.ts:
@Injectable()
export class SideNavService
private openNavSource = new Subject(); // never expose subjects directly
openNav$ = this.openNavSource.asObservable();
openNav = () => this.openNavSource.next();
适当提供,注入到父子中使用
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:
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:
<button (click)="openNav()">Open Nav</button>
然后您可以将服务注入任意组件并根据需要使用它。
【讨论】:
非常棒!感谢您提供这两种方法,因为我肯定迟早会同时使用它们! :) 我可以问一个小问题:像(openNav)
这样的“参数”是什么?这是子视图的某种构造函数参数吗?为什么在第一个示例中是@Output
而不是@Input
?
(openNav) 是标准的角度输出事件绑定。子组件正在输出一个事件,而父组件通过该语法绑定到它。这是一个@Output,因为它是从子级生成的输出,而不是从父级传递给子级的输入。一个例子是您熟悉的 (click)="" 语法。 click 是一个 Angular 框架,提供来自原生 HTML 组件的输出事件,以便于绑定。
啊,明白了。再次感谢! :)
绝对精彩 非常感谢@bryan60 ...第二种方法绝对是一种。干杯以上是关于如何从孩子的父母访问模板引用变量?的主要内容,如果未能解决你的问题,请参考以下文章
React,如何从父母那里访问孩子的状态?无需更新父母的状态