web-dev-qa-db-fra.com

Accès à une propriété dans un composant parent dans Angular2 avec TypeScript

J'essaie actuellement de m'apprendre à utiliser Angular2 et TypeScript après avoir travaillé avec Angular 1. * pendant 4 ans! Quoi qu'il en soit, j'ai une propriété dans un composant de niveau supérieur qui correspond aux données utilisateur provenant d'une source http telle que so ... (il s'agit d'un fichier appelé app.ts).

import {UserData} from './services/user-data/UserData';

Component({
    selector: 'app', // <app></app>
    providers: [...FORM_PROVIDERS],
    directives: [...ROUTER_DIRECTIVES],
    pipes: [],
    template: require('./app.html')
})
@RouteConfig([
    // stuff here
])

export class App {
    // Please note that UserData is an Injectable Service I have written
    userStatus: UserStatus;

    constructor(private userData: UserData) {
        this.userStatus = new UserStatus();
    }

    ngOnInit() {
        this.userData.getUserStatus()
            .subscribe(
            (status) => {
                this.userStatus = status; // I want to access this in my Child Components...
            },
            (err) => {console.log(err);},
            () => {console.log("User status complete");            }
        );
    }
}

Maintenant, j'ai un autre composant qui est un enfant direct du composant de niveau supérieur et dans lequel je voudrais accéder à la propriété du parent 'userStatus', voici l'enfant ... 

Component({
    selector: 'profile',
    template: require('app/components/profile/profile.html'),
    providers: [],
    directives: [],
    pipes: []
})

export class Profile implements OnInit {
    constructor() {

    }

    ngOnInit() {
        // I want to have access with the parent App Component, 'userStatus' propety here... I only want to read this property
    }
}

Maintenant, dans Angular1.x, cela serait facile car je pourrais référencer $parent dans mon contrôleur enfant ou ( ANTI PATTERN ALERT !!! ) Je pourrais être si bête de mettre ces données dans mon $rootScope. Quel serait le meilleur moyen d'accéder au parent dans Angular2? Merci d'avance.

44
Mike Sav

Il y a différentes manières:

export class Profile implements OnInit {
constructor(@Host() parent: App) {
  parent.userStatus ...
}
  • liaison de données
export class Profile implements OnInit {
  @Input() userStatus:UserStatus;
  ...
}

<profile [userStatus]="userStatus">
50
Günter Zöchbauer

J'ai eu le même problème mais je l'ai résolu différemment. Je ne sais pas si c'est une bonne façon de le faire, mais cela fonctionne très bien pour ce dont j'ai besoin.

J'ai utilisé @Inject sur le constructeur du composant enfant, comme ceci:

import { Component, OnInit, Inject } from '@angular/core';
import { ParentComponent } from '../views/parent/parent.component';

export class ChildComponent{
    constructor(@Inject(ParentComponent) private parent: ParentComponent){

    }

    someMethod(){
        this.parent.aPublicProperty = 2;
    }
}

Cela a fonctionné pour moi, il vous suffit de déclarer la méthode ou la propriété que vous souhaitez appeler comme publique.

Dans mon cas, AppComponent gère le routage et j'utilise des badges dans les éléments de menu pour avertir l'utilisateur que de nouveaux messages non lus sont disponibles. Ainsi, chaque fois qu'un utilisateur lit un message, je souhaite que ce compteur soit actualisé. J'appelle donc la méthode d'actualisation de sorte que le numéro affiché dans le menu nav soit mis à jour avec la nouvelle valeur. Ce n'est probablement pas le meilleur moyen mais je l'aime pour sa simplicité.

17
mikesoft

Vous pourriez:

  • Définissez un paramètre userStatus pour le composant enfant et indiquez la valeur lorsque vous utilisez ce composant à partir du parent:

    @Component({
      (...)
    })
    export class Profile implements OnInit {
      @Input()
      userStatus:UserStatus;
    
      (...)
    }
    

    et dans le parent:

    <profile [userStatus]="userStatus"></profile>
    
  • Injectez le parent dans le composant enfant:

    @Component({
      (...)
    })
    export class Profile implements OnInit {
      constructor(app:App) {
        this.userStatus = app.userStatus;
      }
    
      (...)
    }
    

    Faites attention aux dépendances cycliques entre eux.

13
Thierry Templier

J'ai créé un composant générique pour lequel j'ai besoin d'une référence au parent qui l'utilise. Voici ce que je viens avec:

Dans mon composant, j'ai fait un @Input:

@Input()
parent: any;

Puis dans le parent utilisant ce composant:

<app-super-component [parent]="this"> </app-super-component>

Dans le super composant, je peux utiliser tout ce qui est compilé par le parent:

Les attributs:

parent.anyAttribute

Les fonctions :

parent[myFunction](anyParameter)
5
Deunz

Sur Angular 6, j'accède aux propriétés parent en injectant le parent via le constructeur. Pas la meilleure solution mais ça marche:

 constructor(@Optional() public parentComponentInjectionObject: ParentComponent){
    // And access like this:
    parentComponentInjectionObject.thePropertyYouWantToAccess;
}
0
tolga