javascript 为什么把数据推到observable内部的全局数组中,却没有填满数组?

toe95027  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(329)

作为一个新的Angular 开发者,我目前正在做一个Angular 项目。(https://www.flickr.com/services/api/)并将其呈现到我的视图(bandeau.component.html)。因此,要实现此步骤,我在我的服务中使用HttpClientModule中的get()方法它返回一个响应,我负责解析和Map到一个自定义对象(照片特写)我以前在一个可观察的物体里创造过。所以,我的问题是,当我想将Map对象的数据存储在我的服务的全局数组中,并试图通过TypeScript中的console.log()打印它时,“s文件(bandeau.component.ts)时,它会显示一个空数组。
我的观点是get()方法运行一个异步请求。所以在它完成之前,我获取了还没有被get方法处理的数据。所以它用空对象填充了我的数组。但是,我仍然没有解决这个问题的方法。
你能帮我解决这个问题吗
下面是我的代码:
组件:

<form (ngSubmit)="onSubmit()" [formGroup]="flickrSearchForm">
  <div>
    <input formControlName="searchFor" id="text" name="user-input" placeholder="Titre, description, tags etc..."
           type="text">
  </div>

  <p>Rechercher par :</p>
  <div aria-label="Basic radio toggle button group" class="btn-group" role="group">
    <input class="btn-check" formControlName="searchBy" id="all" name="searchBy" type="radio" value="all">
    <label class="btn btn-outline-primary" for="all">Autre</label>

    <input class="btn-check" formControlName="searchBy" id="tags" name="searchBy" type="radio" value="tags">
    <label class="btn btn-outline-primary" for="tags">Tags</label>

  </div>

  <p>Taille :</p>
  <div aria-label="Basic radio toggle button group" class="btn-group" role="group">
    <input class="btn-check" formControlName="extra" id="small" name="extra" type="radio" value="url_s">
    <label class="btn btn-outline-primary" for="small">P</label>

    <input class="btn-check" formControlName="extra" id="medium" name="extra" type="radio" value="url_m">
    <label class="btn btn-outline-primary" for="medium">M</label>

    <input class="btn-check" formControlName="extra" id="big" name="extra" type="radio" value="url_l">
    <label class="btn btn-outline-primary" for="big">G</label>

  </div>

  <div>
    <label for="date-min-upload">Uploadée après le :</label>
    <input formControlName="min_upload_date" id="date-min-upload" name="date-min-upload" type="date">
  </div>

  <div>
    <label for="date-max-upload">Uploadée avant le : </label>
    <input formControlName="max_upload_date" id="date-max-upload" name="date-max-upload" type="date">
  </div>

  <div>
    <label for="date-min-taken">Prise après le :</label>
    <input formControlName="min_taken_date" id="date-min-taken" name="date-min-taken" type="date">
  </div>

  <div>
    <label for="date-max-taken">Prise avant le : </label>
    <input formControlName="max_taken_date" id="date-max-taken" name="date-max-taken" type="date">
  </div>

  <div>
    <label for="safe-search">NSFW :</label>
    <select formControlName="safe_search" id="safe-search" name="safe-search">
      <option value="1">Fiable</option>
      <option value="2">Modéré</option>
      <option value="3">Restreint</option>
    </select>
  </div>

  <div>
    <label for="privacy">Visible pour :</label>
    <select formControlName="privacy_filter" id="privacy" name="privacy">
      <option value="1">Tout le monde</option>
      <option value="2">Uniquement pour les amis</option>
      <option value="3">Uniquement pour la famille</option>
      <option value="4">Uniquement pour la famille</option>
      <option value="5">Privée</option>
    </select>
  </div>

  <div>
    <p>Type de contenu :</p>
    <div>
      <label for="content-types-photos">Video</label>
      <input class="form-check-input" formControlName="content_types" id="content-types-photos" name="content_types" type="checkbox" value="0" (change)="onChecboxChange($event)">
    </div>

    <div>
      <label for="content-types-screenshot">Capture d'écran</label>
      <input class="form-check-input" formControlName="content_types" id="content-types-screenshot" name="content_types" type="checkbox" value="1" (change)="onChecboxChange($event)">
    </div>

    <div>
      <label for="content-types-virtual-photo">Photo virtuelle</label>
      <input class="form-check-input" formControlName="content_types" id="content-types-virtual-photo" name="content_types" type="checkbox" value="2" (change)="onChecboxChange($event)">
    </div>

    <div>
      <label for="content-types-other">Autres</label>
      <input class="form-check-input" formControlName="content_types" id="content-types-other" type="checkbox" name="content_types" value="3" (change)="onChecboxChange($event)">
    </div>

  </div>

  <div class=" color-picker">
    <p>Couleur :</p>
    <div class="color-palette">
      <label for="color-codes-red">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-red" style="background-color: #ff2000" type="checkbox"
               value="0" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-brown">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-brown" style="background-color: #a24615" type="checkbox"
               value="1" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-orange">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-orange" style="background-color: #ff7c00"
               type="checkbox" value="2" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-pink">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-pink" style="background-color: #ff9f9c" type="checkbox"
               value="b" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-yellow">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-yellow" style="background-color: #fffa00"
               type="checkbox" value="4" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-yellow-dark">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-yellow-dark" style="background-color: #ffcf00"
               type="checkbox" value="3" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-green-light">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-green-light" style="background-color: #90e200"
               type="checkbox" value="5" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-green-dark">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-green-dark" style="background-color: #00ab00"
               type="checkbox" value="6" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-blue-light">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-blue-light" style="background-color: #00b2d4"
               type="checkbox" value="7" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-blue-dark">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-blue-dark" style="background-color: #0062c6"
               type="checkbox" value="8" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-purple">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-purple" style="background-color: #8c20ba"
               type="checkbox" value="9" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-pink-dark">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-pink-dark" style="background-color: #f52394"
               type="checkbox" value="a" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-white">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-white" style="background-color: #ffffff" type="checkbox"
               value="c">
      </label>
      <label for="color-codes-grey">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-grey" style="background-color: #7c7c7c" type="checkbox"
               value="d" (change)="onChecboxChange($event)">
      </label>
      <label for="color-codes-black">
        <input class="color-picker-item" formArrayName="color_codes" id="color-codes-black" style="background-color: #000000" type="checkbox"
               value="e" (change)="onChecboxChange($event)">
      </label>
    </div>
  </div>

  <button class="btn btn-primary" type="submit">Rechercher</button>

</form>

bandeau.component.ts(addParameters函数从用户输入中获取数据,处理数据并返回参数I连接API HTTP请求的基本URL):

onSubmit(): void {
    let pf = this.fs.getPhotosFeatures(this.addParameters(this.parameters));
    console.log(pf);
  }

服务:

import { Injectable } from '@angular/core';
import {PhotosFeatures} from "../../Entities/PhotosFeatures";
import {HttpClient } from "@angular/common/http";
import {environment} from "../../../environments/environment";
import {Photos} from "../../Entities/Photos";
import {delay, map, Observable} from "rxjs";
import {FlickrOutput} from "../../Entities/FlickrOutput";

@Injectable({
  providedIn: 'root'
})
export class FlickrService {

  private baseUrl: string = "https://www.flickr.com/services/rest/?api_key=" + environment.apiKeys + "&format=json&nojsoncallback=1&per_page=500&method=flickr.photos.search&";
  public pf: PhotosFeatures[] = [];
  private photos?: Photos[];

  constructor(public http : HttpClient) { }

  getPf() : PhotosFeatures[] {
    return this.pf;
  }

  getPhotosFeatures(requestParam: string) : Observable<PhotosFeatures[]> {
    this.pf = [];
    return this.http.get(this.baseUrl + requestParam)
      .pipe(map((data: any) => {
          delay(10000)
          data.photos.photo.forEach((ph: PhotosFeatures) => {

            }
          )
        return this.pf;
        }
      ))

  }

}

照片特写.ts:

export interface PhotosFeatures {
  id: string;
  server: string;
  secret: string,
  title: string;
}
tsm1rwdh

tsm1rwdh1#

首先,this.pf不会被推送任何数据,因此它将始终保持为空。
现在,需要理解的另一件事是,getPhotosFeatures返回一个可观察值(这是一件好事,因为正如您所说,您正在执行异步操作),但您将其作为一个值进行记录。
一个可观察物在被订阅之前不做任何事情,所以首先要做的就是订阅它:

let pf = this.fs.getPhotosFeatures(this.addParameters(this.parameters)).subscribe(pf=>console.log(pf));

这样,我就订阅了可观察的数据,当数据到达时,传递的函数将被调用,在本例中,我只是简单地将其记录在console.log中。
现在,另一个问题是你的服务中的map,你返回的this.pf总是一个空数组,因为你没有对它做任何事情,而且你的延迟对你放置它的位置没有影响,你需要把它放在你的map之前或之后.

.pipe(delay(10000),map((data: any) => {
      const pf = [];
      data.photos.photo.forEach((ph: PhotosFeatures) => {
            // Do stuff?
            pf.push(ph);
        }
      )
    return pf;
    }
  ));

看,我把PF改成了本地的,而不是服务的属性,我想没有理由引起副作用。我最后像你一样返回了PF,但是现在它应该被填充了,因为我们做了PF。推动它。
我希望这能让事情明朗一点。

相关问题