#angular #rest
#angular #rest
Вопрос:
Как я могу передать функцию подписки, в которой я получаю информацию из REST API от дочернего компонента (agreements.component) к родительскому компоненту (home.component) и вызвать ее в дочернем компоненте с источником событий в ngOnInit(). Я был бы признателен за любую помощь. Я прикрепил код.
Соглашения о ДОЧЕРНИХ КОМПОНЕНТАХ.компонент
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-agreements',
templateUrl: './agreements.component.html',
styleUrls: ['./agreements.component.sass']
})
export class AgreementsComponent implements OnInit {
@Output() getBody = new EventEmitter<any>();
private body;
constructor() { }
ngOnInit() {
this.body=this.getBody.emit();
}
}
<ul>
<li *ngFor="let b of body">{{b.body}}</li>
</ul>
СЛУЖБА
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AgreementsService {
constructor(private http:HttpClient) { }
// Uses http.get() to load data from a single API endpoint
getBodyService(): Observable<any> {
return this.http.get('https://jsonplaceholder.typicode.com/posts');
}
}
РОДИТЕЛЬСКИЙ КОМПОНЕНТ (home.component)
import { Component, OnInit } from '@angular/core';
//import {Customer} from '../model/model';
import {AgreementsService} from '../home/agreements/agreements.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.sass']
})
export class HomeComponent implements OnInit {
private body;
constructor(private _agreementsService: AgreementsService) { }
ngOnInit() {
}
getBody() {
return this._agreementsService.getBodyService().subscribe(
data => { this.body = data, console.log(data)},
err => console.error(err),
() => console.log('done loading foods')
)
}
}
<app-email></app-email>
<app-agreements (getBody)="getBody($event)"></app-agreements>
Ответ №1:
Нет необходимости использовать EventEmitter
. Передайте тело как Input
дочернему компоненту.
ParentComponent — HTML
<div *ngIf="body">
<app-agreements [body]="body"></app-agreements>
</div>
ParentComponent — TS
ngOnInit() {
this.getBody();
}
getBody() {
this._agreementsService.getBodyService().subscribe(
data => {
this.body = data;
},
err => console.error(err),
() => console.log('done loading foods')
)
}
Дочерний компонент — TS
export class AgreementsComponent {
@Input() body;
}
Смотрите мою демонстрацию StackBlitz.
Ответ №2:
нет, вы не можете этого сделать, но есть 2 варианта
- ViewChild
получите компонент app-agreements в home-component от @ViewChild, и когда поступают данные, вы вызываете функцию app-agreements следующим образом
@Component({
selector: "app-home",
templateUrl: "./home.component.html",
styleUrls: ["./home.component.sass"]
})
export class HomeComponent implements OnInit {
private body;
@ViewChild(AgreementsComponent)
agreementsComp: AgreementsComponent;
constructor(private _agreementsService: AgreementsService) {}
ngOnInit() {}
getBody() {
return this._agreementsService.getBodyService().subscribe(
data => {
this.agreementsComp.processData(data);
},
err => console.error(err),
() => console.log("done loading foods")
);
}
}
и внутри компонента соглашений добавьте метод ProcessData.
второй и лучший вариант
- Привязка свойства
добавьте свойство ввода в компонент соглашений, и когда данные поступят, просто назначьте его и прослушайте событие ngOnChanges в компоненте соглашений следующим образом
export class AgreementsComponent implements OnInit, OnChanges {
@Output() getBody = new EventEmitter<any>();
@Input() data: any;
private body;
constructor() {}
ngOnInit() {}
ngOnChanges() {
if (data) {
///Do your logic here
}
}
}
и это html домашнего компонента
<app-agreements [data]="body" (getBody)="getBody($event)"></app-agreements>