web-dev-qa-db-fra.com

Comment changer la variable parent du composant enfants?

Cette question est assez simple mais je ne peux pas m'en débarrasser.

J'ai un <header> dans le modèle parent et je dois le faire disparaître lors de l'affichage du modèle pour enfants via le module de routage. Ce que je pense, c’est d’ajouter une classe à la balise d’en-tête pour pouvoir la cacher via CSS. Voici ce que j'ai

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.
}
7
Mdkusuma

Vous pouvez utiliser output emitter

Dans votre composant enfant,

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);
    }
}

Chez le parent,

export class AppComponent {
  hide = false; 
 onHide(val: boolean) {
    this.hide=val;
  }
}
8
Suraj Rao

Dans votre app.component.ts, vous pouvez vérifier votre URL et définir la valeur de la variable hide comme ci-dessous:

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;
        }
      }
    });
  }

}
3
ranakrunal9

Je suis tombé sur le même phénomène très récemment avec Angular 6. 

Je voulais accéder à une variable appartenant à un composant parent ou à un grand-parent et la modifier. Voir l'image ci-dessous. Je veux accéder et modifier une variable qui appartient à Tom, de Jim (un enfant de Tom) et de Sara (un petit-fils de Tom).

 enter image description here

Il existe peut-être d'autres solutions, mais l'approche que j'ai utilisée pour résoudre ce problème consiste à utiliser ViewContainerRef. Je dois injecter la variable ViewContainerRef au constructeur du composant enfant, c'est-à-dire accéder au composant parent et traverser le ou les nœuds parents pour trouver la variable parent. 

Injecter au constructeur,

constructor(private viewContainerRef: ViewContainerRef) { }

Accéder au nœud parent et le traverser,

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

J'ai fait un exemple de StackBlitz avec le scénario que je vous ai donné dans l'image ci-dessus. 

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

J'espère que quelqu'un trouvera cela utile.

Je vous remercie.

1
Anjana Silva