如何从子级中的父级访问模板引用变量?

时间:2017-10-25 20:18:16

标签: angular

我试图分别围绕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中将这样的引用传递给“no no”,我实际上应该使用基于事件的触发器或类似的东西?

1 个答案:

答案 0 :(得分:4)

这是正常的父/子组件通信。您可以这样做的方法是在子项上公开输出事件:

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,甚至可能在嵌套的地方,你可能只想解决所有情况下的问题并使用共享服务observable:

侧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>

然后您可以将服务注入任意组件并根据需要使用它。