Подтвердить что ты не робот

Доступ к свойству в родительском компоненте

У меня есть свойство в компоненте верхнего уровня, который использует данные из источника HTTP, например, так (это в файле с именем 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");            }
        );
    }
}

Теперь у меня есть другой Компонент, который является прямым потомком Компонента верхнего уровня, и в нем я хотел бы получить доступ к родительскому свойству ' userStatus ', вот дочерний:

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

Теперь в Angular 1.x это было бы легко, поскольку я мог ссылаться на $parent в моем дочернем контроллере или (ANTI PATTERN ALERT !!!) Я мог бы быть настолько глуп, чтобы поместить эти данные в мой $rootScope.

Каков наилучший способ доступа к родителю в Angular 2?

4b9b3361

Ответ 1

Существуют разные способы:

export class Profile implements OnInit {
constructor(@Host() parent: App) {
  parent.userStatus ...
}
  • привязки данных
export class Profile implements OnInit {
  @Input() userStatus:UserStatus;
  ...
}

<profile [userStatus]="userStatus">

Ответ 2

У меня была такая же проблема, но я решил ее по-другому. Я не знаю, хорошо ли это, но он отлично работает для того, что мне нужно.

Я использовал @Inject в конструкторе дочернего компонента, например:

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

Это сработало для меня, вам нужно только объявить метод или свойство, которое вы хотите вызвать как общедоступное.

В моем случае AppComponent обрабатывает маршрутизацию, и я использую значки в элементах меню, чтобы предупредить пользователя о наличии новых непрочитанных сообщений. Поэтому каждый раз, когда пользователь читает сообщение, я хочу, чтобы этот счетчик обновлялся, поэтому я вызываю метод обновления, чтобы номер в навигаторе меню обновлялся с новым значением. Это, вероятно, не самый лучший способ, но мне нравится его простота.

Ответ 3

Вы можете:

  • Определите параметр userStatus для дочернего компонента и укажите значение при использовании этого компонента из родителя:

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

    и в родительском:

    <profile [userStatus]="userStatus"></profile>
    
  • Вставьте родительский элемент в дочерний компонент:

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

    Будьте осторожны с циклическими зависимостями между ними.

Ответ 4

Я создал общий компонент, где мне нужна ссылка на родителя, использующего его. Вот что я придумал:

В моем компоненте я сделал @Input:

@Input()
parent: any;

Затем в родительском элементе:

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

В суперкомпонентном я могу использовать что-либо, компилирующееся из родителя:

Атрибуты:

parent.anyAttribute

Функции:

parent[myFunction](anyParameter)

Ответ 5

На Angular 6 я получаю доступ к родительским свойствам, вводя родительский объект через конструктор. Не лучшее решение, но оно работает:

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

Ответ 6

Поскольку взаимодействие между родителями и детьми не является легкой задачей. Но при наличии ссылки на родительский компонент в дочернем компоненте было бы намного легче взаимодействовать. В моем методе вы должны сначала передать ссылку на родительский компонент, вызвав функцию дочернего компонента. Вот для этого метода.

Код для дочернего компонента.

    import { Component, Input,ElementRef,Renderer2 } from '@angular/core';

    import { ParentComponent } from './parent.component';

    @Component({
      selector: 'qb-child',
      template: '<div class="child"><button (click)="parentClickFun()">Show text Of Parent Element</button><button (click)="childClickFun()">Show text Of Child Element</button><ng-content></ng-content></div>',
      styleUrls: ['./app.component.css']
    })
    export class ChildComponent  {
      constructor(private el: ElementRef,private rend: Renderer2){

      };

      qbParent:ParentComponent; 
      getParent(parentEl):void{
        this.qbParent=parentEl;
        console.log(this.el.nativeElement.innerText);
      }
      @Input() name: string;
      childClickFun():void{
        console.log("Properties of Child Component is Accessed");
      }

      parentClickFun():void{
        this.qbParent.callFun();
      }
    }

Это код для родительского компонента

import { Component, Input , AfterViewInit,ContentChild,ElementRef,Renderer2} from '@angular/core';

import { ChildComponent } from './child.component';

@Component({
  selector: 'qb-parent',
  template: '<div class="parent"><ng-content></ng-content></div>',
  styleUrls: ['./app.component.css']
})
export class ParentComponent implements AfterViewInit {
  constructor(private el: ElementRef,private rend: Renderer2){

  };
  @Input() name: string;
  @ContentChild(ChildComponent,{read:ChildComponent,static:true}) qbChild:ChildComponent;

  ngAfterViewInit():void{
    this.qbChild.getParent(this);
  }

  callFun():void{
    console.log("Properties of Parent Component is Accessed");
  }

}

Здесь мы передаем родительский компонент, вызывая функцию дочернего компонента. Ссылка ниже является примером этого метода. Нажмите здесь !