如何更改子组件的父变量?

问题描述 投票:0回答:4

这个问题很简单,但我就是摆脱不了。

我在父模板中有一个

<header>
,当通过路由模块显示子模板时我需要它消失。我期望的是在 header 标签中添加一个类,这样我就可以通过 CSS 隐藏它。这就是我拥有的:

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'app',
  template: `
    <header [class.hidden]="hide">
      <h1>My App</h1>
      <ul>
            <li><a href="/home"></a></li>
            <li><a href="/showoff"></a></li>
      </ul>
    </header>
    <router-outlet></router-outlet>
  `
})

export class AppComponent {
  hide = false; // <-- This is what I need to change in child component
}

app-routing.module.ts

import { RouterModule, Routes } from '@angular/router';

import { HomeComponent } from './welcome.component';
import { ShowOffComponent } from './show.off.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'showoff', component: ShowOffComponent },
];

export const AppRouting = RouterModule.forRoot(routes, {
  useHash: true
});

show.offf.component.ts

import { Component } from '@angular/core';
@Component({
   selector: 'app-showoff',
   template: `
       <h2>Show Off</h2>
       <div>Some contents...</div>
   `
})

export class ShowOffComponent {
   hide = true; // <-- Here is the problem.
                // I don't have any idea how to reach parent variables.
}
angular angular2-routing angular-components
4个回答
20
投票

您可以使用输出发射器

在您的子组件中,

import { Component } from '@angular/core';
@Component({
   selector: 'app-showoff',
   template: `
       <h2>Show Off</h2>
       <div>Some contents...</div>
   `
})

export class ShowOffComponent {
    @Output() onHide = new EventEmitter<boolean>();
    setHide(){
       this.onHide.emit(true);
    }
}

在家长中,

export class AppComponent {
  hide = false;

  changeHide(val: boolean) {
    this.hide = val;
  }
}

使用该事件发射器向父级添加子级,

<app-showoff (onHide)="changeHide($event)"></app-showoff>

10
投票

我最近在 Angular 6 中遇到了同样的现象。

我想访问和更改属于父组件或祖父组件的变量。请参见下图。我想访问和更改属于 Tom 的变量,来自 Jim(Tom 的孩子)和 Sara(Tom 的孙子)。

enter image description here

可能还有其他一些解决方案,但我用来克服这个问题的方法是使用

ViewContainerRef
。我必须将
ViewContainerRef
注入到子组件的构造函数中,我需要访问父组件并遍历父节点(或多个节点)以查找父变量。

注入构造函数,

constructor(private viewContainerRef: ViewContainerRef) { }

访问并遍历到父节点,

getParentComponent() {
    return this.viewContainerRef[ '_data' ].componentView.component.viewContainerRef[ '_view' ].component
}

我用上图中给你的场景制作了一个 StackBlitz 示例。

https://stackblitz.com/edit/angular-comms


3
投票

在您的

app.component.ts
中,您可以检查您的 URL 并设置
hide
变量值,如下所示:

import { Component } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';

@Component({
  selector: 'app',
  template: `
    <header [class.hidden]="hide">
      <h1>My App</h1>
      <ul>
            <li><a href="/home"></a></li>
            <li><a href="/showoff"></a></li>
      </ul>
    </header>
    <router-outlet></router-outlet>
  `
})

export class AppComponent {
  hide = false; // <-- This is what I need to change in child component

  constructor(private router: Router){}

  public ngOnInit() {
    this.router.events.subscribe((events) => {
      if (events instanceof NavigationStart) {
        if (events.url === '/' || events.url === '/home') {
          this.hide = false;
        } else {
          this.hide = true;
        }
      }
    });
  }

}

0
投票

不太直接,但(恕我直言)更准确地实现这一目标的方法是使用服务。

  1. 创建parent-to-child.service.ts 文件并创建主题属性

    导出类 ParentToChildService { 显示标题=新主题(); }

  2. 通过父组件和子组件中的构造函数将其注入:

    构造函数(私有 ptcService:ParentToChildService ){}

  3. 使用 ngIf(或者你可以使用 ngClass,如果你坚持使用 CSS 方法)将标头组件绑定到其 TS 文件中的属性:

html:

<header *ngIf="showStatus">

TS:
showStatus: boolean = true;  // true by default ptcSubscription: Subscription;

  1. 在标头组件的 ngInit 上订阅该主题:

    ngOnInit(): { this.ptcSubscription = this.ptcService.showHeader.subscribe( (新状态:布尔值)=> { this.showStatus = newStatus }); } ); }

  2. 在您的子组件中,每当您需要隐藏

    <header
    > 时,请在服务主题上调用
    next

    this.ptcService.showHeader.next(false); //隐藏标题

© www.soinside.com 2019 - 2024. All rights reserved.