Accessing a property in a parent Component in Angular2 with TypeScript

I'm currently trying to teach myself Angular2 and TypeScript after happily working with Angular 1.* for the last 4 years! Anyway, I have a property in a top level Component that is user data from a http source like so... (this is in a file called 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");            }
        );
    }
}

Now I have another Component that is a direct child of the top level Component and within it I would like to access the parent's property ' userStatus ', here is the child...

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

Now in Angular1.x this would be easy as I could reference $parent in my child controller or ( ANTI PATTERN ALERT!!! ) I could be so foolish to put this data in my $rootScope . What would be the best way to access the parent in Angular2? Thanks in advance.


There are different way:

  • global service

  • see also
  • https://github.com/escardin/angular2-community-faq/blob/master/services.md#how-do-i-communicate-between-components-using-a-shared-service
  • Global Events in Angular 2
  • Plunker
  • service shared by parent and injected to the child

  • similar to global service but listed in providers or viewProviders in the parent instead of boostrap(...) and only available to children of parent.
  • parent injected to the child and accessed directly by the child

  • disadvantage: tight coupling
  • export class Profile implements OnInit {
    constructor(@Host() parent: App) {
      parent.userStatus ...
    }
    
  • data-binding
  • export class Profile implements OnInit {
      @Input() userStatus:UserStatus;
      ...
    }
    
    <profile [userStatus]="userStatus">
    

    You could:

  • Define a userStatus parameter for the child component and provide the value when using this component from the parent:

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

    and in the parent:

    <profile [userStatus]="userStatus"></profile>
    
  • Inject the parent into the child component:

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

    Be careful about cyclic dependencies between them.


  • I had the same problem but I solved it differently. I don't know if it's a good way of doing it, but it works great for what I need.

    I used @Inject on the constructor of the child component, like this:

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

    This worked for me, you only need to declare the method or property you want to call as public.

    In my case, the AppComponent handles the routing, and I'm using badges in the menu items to alert the user that new unread messages are available. So everytime a user reads a message, I want that counter to refresh, so I call the refresh method so that the number at the menu nav gets updated with the new value. This is probably not the best way but I like it for its simplicity.

    链接地址: http://www.djcxy.com/p/40692.html

    上一篇: Angular 2键盘事件

    下一篇: 使用TypeScript在Angular2中访问父组件中的属性