首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试使用输入装饰器将对象从api传递给子组件

尝试使用输入装饰器将对象从api传递给子组件
EN

Stack Overflow用户
提问于 2020-11-17 12:20:55
回答 5查看 122关注 0票数 0

我有一个父组件,它使用服务从api接收数据。我需要将此数据传递给子组件,因为我不想再次调用api (严格规则)。我可以访问父组件中的数据,但不能在子组件中获取数据。我试过很多不同的方法。

代码语言:javascript
复制
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);

      }
    )
  }

}

父模板

代码语言:javascript
复制
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>

子组件

代码语言:javascript
复制
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);


  }

}

子模板

代码语言:javascript
复制
<span *ngIf="data"></span>
<div *ngFor="let res of data">
  <h1>{{data?.name}}</h1>
  <p>{{data?.url}}</p>
</div>
hi

没有响应。

我正在尝试使用BehaviorSubject,这样我就可以在几个组件之间共享数据。我的问题是,我不知道如何将数据从我的函数转移到一个变量,以便我可以在其他组件中使用它。

这是我的服务文件:

代码语言:javascript
复制
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

我知道了如何在这两个组件中使用它,而不是在服务中声明变量,但我仍然想知道

EN

回答 5

Stack Overflow用户

发布于 2020-11-17 12:59:46

备注主题导入所需的库,例如:

子组件

代码语言:javascript
复制
@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);
        });
    } 
  }

父组件

代码语言:javascript
复制
shareData: BehaviorSubject<any> = new BehaviorSubject({});

在你从后端接收数据的地方编写下面的代码。

代码语言:javascript
复制
this.shareData.next({ data: responseData});

html

代码语言:javascript
复制
<app-starship *ngFor="let res of starship.results" [data]="shareData"></app-starship>
票数 0
EN

Stack Overflow用户

发布于 2020-11-17 13:58:05

您也可以使用BehaviorSubject

service.ts

代码语言:javascript
复制
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.component.ts

代码语言:javascript
复制
ngOnInit(){
   this.loadStarshipList();

  }
  loadStarshipList(){
    this.swapi.getStarshipList().subscribe(
      res => {
        this.starship = res;
        console.log(res);

      }
    )
  }

child.component.ts

代码语言:javascript
复制
data:any;

ngOnInit()
this.swapi.getSList().subscribe(
      res => {
        this.data = res;
        console.log(res);

      }
    )
    }
票数 0
EN

Stack Overflow用户

发布于 2020-11-17 14:09:13

在父模板上不需要多个ngFor。将res直接传递给其中包含result数组的子对象。

代码语言:javascript
复制
<p *ngFor="let res of starship?.results" >{{res?.name}}
 <app-starship [data]="res"></app-starship>

子组件:

代码语言:javascript
复制
  ngOnInit(): void {
   console.log(this.data); //check you have data or not here
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64869315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档