代码之家  ›  专栏  ›  技术社区  ›  Stefan Falk

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

  •  6
  • Stefan Falk  · 技术社区  · 7 年前

    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>
    

    当然,这失败了,因为我无法引用 侧导航 -那么我如何访问 侧导航 正确地从孩子内部?

    或者在Angular2中传递这样的引用是“no no”吗?我真的应该使用基于事件的触发器或类似的东西吗?

    1 回复  |  直到 7 年前
        1
  •  6
  •   bryan60    7 年前

    这是正常的父/子组件通信。您可以这样做,只需在子级上公开输出事件:

    父母亲组成部分html摘录:

    <child-component (openNav)="sidenav.open()"></child-component>
    

    小孩组成部分ts:

    @Output() openNav = new EventEmitter();
    

    小孩组成部分html:

    <button (click)="openNav.emit()">Open Nav</button>
    

    侧导航。服务ts:

    @Injectable()
    export class SideNavService {
        private openNavSource = new Subject(); // never expose subjects directly
        openNav$ = this.openNavSource.asObservable();
    
        openNav = () => this.openNavSource.next();
    }
    

    适当提供,并将其注入父母和孩子体内使用

    父母亲组成部分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
    }
    

    小孩组成部分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
    }
    

    小孩组成部分html:

    <button (click)="openNav()">Open Nav</button>
    

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