Поиск…


Синтаксис

  • <element [variableName]="value"></element> //Declaring input to child when using @Input() method.
  • <element (childOutput)="parentFunction($event)"></element> //Declaring output from child when using @Output() method.
  • @Output() pageNumberClicked = new EventEmitter(); //Used for sending output data from child component when using @Output() method.
  • this.pageNumberClicked.emit(pageNum); //Used to trigger data output from child component. when using @Output() method.
  • @ViewChild(ComponentClass) //Property decorator is required when using ViewChild.

параметры

название Значение
количество страниц Используется для указания количества страниц, которые должны быть созданы для дочернего компонента.
pageNumberClicked Имя выходной переменной в дочернем компоненте.
pageChanged Функция в родительском компоненте, выполняющая вывод дочерних компонентов.

Родительский - взаимодействие с ребенком с использованием свойств @Input & @Output

У нас есть DataListComponent, который показывает данные, которые мы извлекаем из службы. DataListComponent также имеет PagerComponent, поскольку он является дочерним.

PagerComponent создает список номеров страниц на основе общего количества страниц, которые он получает от DataListComponent. PagerComponent также позволяет знать DataListComponent, когда пользователь нажимает на любой номер страницы через свойство Output.

import { Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataListService } from './dataList.service';
import { PagerComponent } from './pager.component';

@Component({
    selector: 'datalist',
    template: `
        <table>
        <tr *ngFor="let person of personsData">
            <td>{{person.name}}</td>
            <td>{{person.surname}}</td>
        </tr> 
        </table>

        <pager [pageCount]="pageCount" (pageNumberClicked)="pageChanged($event)"></pager>
    `
})
export class DataListComponent {
    private personsData = null;
    private pageCount: number;

    constructor(private dataListService: DataListService) { 
        var response = this.dataListService.getData(1); //Request first page from the service
        this.personsData = response.persons;
        this.pageCount = response.totalCount / 10;//We will show 10 records per page.
    }

    pageChanged(pageNumber: number){
        var response = this.dataListService.getData(pageNumber); //Request data from the service with new page number
        this.personsData = response.persons;
    }
}

@NgModule({
    imports: [CommonModule],
    exports: [],
    declarations: [DataListComponent, PagerComponent],
    providers: [DataListService],
})
export class DataListModule { }

PagerComponent перечисляет все номера страниц. Мы устанавливаем событие click для каждого из них, чтобы мы могли сообщить родителям о количестве щелкнутых страниц.

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
    selector: 'pager',
    template: `
    <div id="pager-wrapper">
        <span *ngFor="#page of pageCount" (click)="pageClicked(page)">{{page}}</span>
    </div>
    `
})
export class PagerComponent {
    @Input() pageCount: number;
    @Output() pageNumberClicked = new EventEmitter();
    constructor() { }

    pageClicked(pageNum){
        this.pageNumberClicked.emit(pageNum); //Send clicked page number as output
    }
}

Родитель - взаимодействие с ребенком с помощью ViewChild

Viewchild предлагает одностороннее взаимодействие от родителя к ребенку. При использовании ViewChild нет обратной связи или выхода из дочернего элемента.

У нас есть DataListComponent, который показывает некоторую информацию. DataListComponent имеет PagerComponent, поскольку он является дочерним. Когда пользователь выполняет поиск в DataListComponent, он получает данные из службы и просит PagerComponent обновить макет пейджинга на основе нового количества страниц.

import { Component, NgModule, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataListService } from './dataList.service';
import { PagerComponent } from './pager.component';

@Component({
    selector: 'datalist',
    template: `<input type='text' [(ngModel)]="searchText" />
               <button (click)="getData()">Search</button>
        <table>
        <tr *ngFor="let person of personsData">
            <td>{{person.name}}</td>
            <td>{{person.surname}}</td>
        </tr> 
        </table>

        <pager></pager>
    `
})
export class DataListComponent {
    private personsData = null;
    private searchText: string;

    @ViewChild(PagerComponent)
    private pagerComponent: PagerComponent;

    constructor(private dataListService: DataListService) {}
    
    getData(){
        var response = this.dataListService.getData(this.searchText);
        this.personsData = response.data;
        this.pagerComponent.setPaging(this.personsData / 10); //Show 10 records per page
    }
}

@NgModule({
    imports: [CommonModule],
    exports: [],
    declarations: [DataListComponent, PagerComponent],
    providers: [DataListService],
})
export class DataListModule { }

Таким образом, вы можете вызывать функции, определенные в дочерних компонентах.

Детский компонент недоступен до отображения родительского компонента. При попытке доступа к ребенку , прежде чем родители AfterViewInit жизни Cyle крючок вызовет исключение.

Двунаправленное взаимодействие родитель-ребенок через службу

Сервис, который используется для связи:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class ComponentCommunicationService {

    private componentChangeSource = new Subject();
    private newDateCreationSource = new Subject<Date>();

    componentChanged$ = this.componentChangeSource.asObservable();
    dateCreated$ = this.newDateCreationSource.asObservable();

    refresh() {
        this.componentChangeSource.next();
    }
    
    broadcastDate(date: Date) {
        this.newDateCreationSource.next(date);
    }
}

Родительский компонент:

import { Component, Inject } from '@angular/core';
import { ComponentCommunicationService } from './component-refresh.service';

@Component({
    selector: 'parent',
    template: `
    <button (click)="refreshSubsribed()">Refresh</button>
    <h1>Last date from child received: {{lastDate}}</h1>
    <child-component></child-component>
    `
})
export class ParentComponent implements OnInit {

    lastDate: Date;
    constructor(private communicationService: ComponentCommunicationService) { }

    ngOnInit() {
        this.communicationService.dateCreated$.subscribe(newDate => {
            this.lastDate = newDate;
        });
    }

    refreshSubsribed() {
        this.communicationService.refresh();
    }
}

Детский компонент:

import { Component, OnInit, Inject } from '@angular/core';
import { ComponentCommunicationService } from './component-refresh.service';

@Component({
    selector: 'child-component',
    template: `
    <h1>Last refresh from parent: {{lastRefreshed}}</h1>
    <button (click)="sendNewDate()">Send new date</button>
    `
})
export class ChildComponent implements OnInit {

    lastRefreshed: Date;
    constructor(private communicationService: ComponentCommunicationService) { }

    ngOnInit() {
        this.communicationService.componentChanged$.subscribe(event => {
            this.onRefresh();
        });
    }

    sendNewDate() {
        this.communicationService.broadcastDate(new Date());
    }

    onRefresh() {
        this.lastRefreshed = new Date();
    }
}

AppModule:

@NgModule({
    declarations: [
        ParentComponent,
        ChildComponent
    ],
    providers: [ComponentCommunicationService],
    bootstrap: [AppComponent] // not included in the example
})
export class AppModule {}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow