如何在 Angular 17 中显示从一个组件中的 api 到另一组件的响应

问题描述 投票:0回答:1

这是我的服务代码:

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

@Injectable({
  providedIn: 'root'
})
export class ResponseService {
  private responseDataSubject = new BehaviorSubject<any>(null);
  responseData$ = this.responseDataSubject.asObservable();

  constructor() { }

  setResponseData(data: any) {
    console.log('Response data set:', data);
    this.responseDataSubject.next(data);
  }
}

这是我的第一个组件 Typescript 代码:

this.http.post<any>('url link', requestBody)
      .subscribe({
        next: response => {
          console.log(response);
          this.loader.stop();
          // Store the response in the shared service
          this.responseService.setResponseData(response);
          
          // Redirect to MyprojectsComponent
          this.router.navigate(['/myprojects']);
        },
        error: error => {
          console.error('Error occurred:', error);
        }
      });

这是我的第二个组件 TS:

constructor(private router: Router,public responseService:ResponseService , private route:ActivatedRoute) { }
 ngOnInit(): void {
    this.responseService.responseData$.subscribe({
      next: (response) => {
        if (response !== null) {
          console.log('Response from ScribblePadComponent:', response);
          // Proceed with handling the response data
        } else {
          console.error('Response from ScribblePadComponent is null.');
        }
      },
      error: (error) => {
        console.error('Error fetching response from ScribblePadComponent:', error);
      }
    });
    this.fetchData(); // Initial data fetch

这是我的第二个组件 Html:

 <div class="item pos-rel mob-style" *ngFor="let item of row.items">
              <div class="content-wrapper general-box-shadow" style="flex-wrap: wrap;">
                <div class="col-md-8">
                  <div class="content">
                    <div class="circle-container">
                      <div class="number-circle">{{ item.id }}</div>
                    </div>
                    <div style="padding: 10px 74px;" class="list-cards" >
                      <p style="font-size: 14px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit, </p>
                      <p *ngIf="item.collapsed">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
                      <!-- <button (click)="toggleDescription(item)" style="background-color: #e15ed2;"> {{getButtonName(item)}} </button>
                      <button style="background-color: #a44de3;"> Related Movies </button>
                      <button style="background-color: #ae81ff;"> Edit </button> -->
                      <span (click)="toggleDescription(item)" class="f-16" title="Expand/Collapse">
                        <i class="fas fa-chevron-down" [class.rot180]="item.collapsed"></i>
                      </span>
                      <span class="f-16" title="Related Movies"><i class="fas fa-film"></i></span>
                      <span class="f-16" title="Edit"><i class="fas fa-pen"></i></span>
                    </div>
                  </div>
                </div>

这是我从 API 获得的示例响应,但它没有发送到第二个组件..它总是显示 null:

Response data set: {
    "logline_1": [
        "A street fighter battles for survival in the underground world of dog fights. When he refuses to kill a defeated opponent, he becomes the next target. Now, he must outsmart the syndicate to save his own life.",
        "Jake, a seasoned street fighter, dominates the gritty underground scene of dog fights. His moral compass is tested when he's ordered to kill a defeated rival, but he refuses. The syndicate running the fights marks him for death, thrusting him into a deadly game of cat and mouse. With the help of a former opponent turned ally, Jake devises a plan to dismantle the syndicate from within. As the final showdown looms, Jake's skills are put to the ultimate test. Will he survive the fight of his life, or will the syndicate claim another victim?",
        "Fight Club"
    ],
    "logline_2": [
        "An undercover cop infiltrates a brutal street fighting ring. Her mission turns deadly when she's ordered to fight to the death. She must expose the corrupt officials before her identity is revealed.",
        "Detective Sarah Connors goes deep undercover to bring down a notorious street fighting ring. She earns the trust of the organizers, but her cover is jeopardized when she's forced into a kill-or-be-killed match. Sarah's moral dilemma intensifies as she faces an innocent opponent in the ring. Time is running out as she scrambles to gather evidence against the corrupt officials behind the fights. With her identity on the brink of exposure, Sarah must make a life-changing decision. Can she maintain her cover and serve justice, or will the brutal world she's infiltrated consume her?",
        "Warrior"
    ],
angular angularjs typescript
1个回答
0
投票

在我看来,您在这里混淆了可观察对象和行为主题。

Observable - 一次性交易。订阅时观察结果

BehaviorSubject - 获取初始结果(通常为空),但也会在订阅时接收任何更改

所以我会将您的服务更改为:-

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

@Injectable({
  providedIn: 'root'
})
export class ResponseService {
public responseDataSubject = new BehaviorSubject<any>(null);

  constructor() { }

  setResponseData(data: any) {
    console.log('Response data set:', data);
    this.responseDataSubject.next(data);
  }
}

然后只需订阅行为主题...这里不需要 Observable

constructor(private router: Router,public responseService:ResponseService , private route:ActivatedRoute) { }
 ngOnInit(): void {
    this.responseService.responseDataSubject.subscribe({
      next: (response) => {
        if (response !== null) {
          console.log('Response from ScribblePadComponent:', response);
          // Proceed with handling the response data
        } else {
          console.error('Response from ScribblePadComponent is null.');
        }
      },
      error: (error) => {
        console.error('Error fetching response from ScribblePadComponent:', error);
      }
    });
    this.fetchData(); // Initial data fetch
© www.soinside.com 2019 - 2024. All rights reserved.