我有一个父组件,它使用服务从api接收数据。我需要将这些数据传递给子组件,因为我不想再次调用api(严格规则(。我可以访问父组件中的数据,但不能在子组件中获取数据。我试过很多不同的方法。
import { Component, OnInit, ViewChild } from '@angular/core';
import {ActivatedRoute} from "@angular/router";
import {SwapiService} from "../../models/swapi.service";
import {Starship} from "../../models/starship";
// import {MatTableDataSource} from '@angular/material/table';
// import {MatPaginator} from '@angular/material/paginator';
@Component({
selector: 'app-starships',
templateUrl: './starships.component.html',
styleUrls: ['./starships.component.css']
})
export class StarshipsComponent implements OnInit {
public starship: Starship[]
url: string;
constructor(private swapi: SwapiService, private route: ActivatedRoute) {
}
ngOnInit(): void {
this.loadStarshipList();
}
loadStarshipList(): void {
this.swapi.getStarshipList().subscribe(
res => {
this.starship = res;
console.log(res);
}
)
}
}
父模板
span *ngIf="starship">
<p *ngFor="let res of starship?.results" >{{res?.name}}
<app-starship *ngFor="let res of starship.results" [data]="res?.results"></app-starship>
<!-- <span [res1]="res1"></span>-->
<button routerLink="/starships/{{res?.url}}">Starship Details</button>
</p>
</span>
子组件
import { Component, Input, OnInit } from '@angular/core';
// import {Starships} from "../../models/starship";
import {SwapiService} from "../../models/swapi.service";
import {ActivatedRoute} from "@angular/router";
import {StarshipsComponent} from "../starships/starships.component";
@Component({
selector: 'app-starship',
templateUrl: './starship.component.html',
styleUrls: ['./starship.component.css']
})
export class StarshipComponent implements OnInit {
// public starship: Starship[]
private url: string;
@Input() data;
constructor(private swapi: SwapiService,
private route: ActivatedRoute,
private activatedRoute: ActivatedRoute,
) {
}
ngOnInit(): void {
this.url = this.route.snapshot.paramMap.get('url');
console.log(this.url);
}
}
子模板
<span *ngIf="data"></span>
<div *ngFor="let res of data">
<h1>{{data?.name}}</h1>
<p>{{data?.url}}</p>
</div>
hi
没有回应。
我正在尝试使用BehaviorSubject,以便在多个组件之间共享数据。我的问题是,我不知道如何将数据从函数传递到变量,以便在其他组件中使用它。
这是我的服务文件:
import { Injectable } from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {BehaviorSubject, Observable} from "rxjs";
import {map, skipWhile, tap} from 'rxjs/operators';
import {Starship} from "./starship";
@Injectable({
providedIn: 'root'
})
export class SwapiService {
private apiData = new BehaviorSubject<Starship[]>(null)
public currentData = this.apiData.asObservable()
baseURL = 'https://swapi.dev/api/';
constructor(private http: HttpClient) { }
getStarshipList(page?: number): Observable<Starship[]> {
return this.http.get<Starship[]>(`${this.baseURL}starships?format=json${this.getByPage(page)}`)
.pipe(
map(resp => resp['results']),)
;
}
getByPage(page: number): string {
if (page) { return '&page=' + page; } else { return ''; }
}
setData(data) {
this.apiData.next(data)
}
}
如何将getStarshipList接收到的数据传输到变量,以便使用setData函数进行传递。我知道这似乎是一个愚蠢的问题,但我尝试了很多不同的方法,但都做不好。
@Abhinav Aggarwal
我想好了如何在不声明服务中的变量的情况下在两个组件中使用它,但我仍然想知道
注意导入所需库,例如:主题
子组件
@Input() data: BehaviorSubject<any>;
ngUnsubscribe: any = new Subject();
ngOnInit(){
this.listenParentDataChanges();
}
listenParentDataChanges() {
if (this.data) {
this.data.asObservable().takeUntil(this.ngUnsubscribe)
.subscribe(responseData => {
console.log("-data--",data);
});
}
}
父组件
shareData: BehaviorSubject<any> = new BehaviorSubject({});
下面的代码写下您从后端接收数据的位置。
this.shareData.next({ data: responseData});
html
<app-starship *ngFor="let res of starship.results" [data]="shareData"></app-starship>
您也可以使用BehaviorSubject
服务.ts
private sList = new BehaviorSubject<any>(null);
getStarshipList() {
return this.http.get(`url`).pipe(
tap((data: any) => this.sList.next(data);
);
}
getSlist() {
return this.sList.asObservable().pipe(skipWhile(val => val === null));
}
parent.com组件.ts
ngOnInit(){
this.loadStarshipList();
}
loadStarshipList(){
this.swapi.getStarshipList().subscribe(
res => {
this.starship = res;
console.log(res);
}
)
}
child.component.ts
data:any;
ngOnInit()
this.swapi.getSList().subscribe(
res => {
this.data = res;
console.log(res);
}
)
}
父模板上不需要多个ngFor
。将res
直接传递给其中包含result
数组的子级。
<p *ngFor="let res of starship?.results" >{{res?.name}}
<app-starship [data]="res"></app-starship>
子组件:
ngOnInit(): void {
console.log(this.data); //check you have data or not here
}
建议:-首先了解生命周期挂钩是如何工作的。以及angular为什么引入ngOnChanges。研究生命周期挂钩和变化检测。
您的问题:-您正在将变量从父级传递到子级。其在父级的初始化阶段没有数据并且是未定义的。您已经将其传递给子组件,因此您没有数据。Api在两个视图都已创建之后提供数据。并且角度分量不知道数据被改变。
解决方案:-
选项1:当父组件接收到数据时,您应该创建子组件。
或
选项2:订阅父组件进行更改检测
或
选项3:对父组件和子组件进行更改检测。
在您的子组件中。。。在ngOnInIt方法之后,使用上面的代码并导入&从angular/core实现ngOnChanges,我希望它能起作用。
导入:从"@angular/core"导入{OnChanges};
实现:导出类StarshipComponent实现OnInit,OnChanges{}
ngOnChanges(changes: SimpleChanges): void {
if (changes.data.currentValue) {
this.data = changes.data.currentValue;
}
}