如何使用一个可观察的一个来更新另一个

发布于 2025-01-24 13:47:31 字数 4704 浏览 0 评论 0原文

我正在尝试使用可观察的收藏夹$构建同一类型的其他数组时。我期望fairition $可观察到的可观察到的类型code> corversy的数组,并且我可以设置一个类变量,以便使用其内容更新。我正在在ngoninit()中进行订阅。

在我的服务的函数中,我正在尝试迭代University对象的收到的列表,并设置属性iSfavureite值,如果它们的等效对象在<<<<代码>收藏夹$ 可观察的数组。

这是不起作用的,我不知道为什么...

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { University } from './university.model';
import { map } from 'rxjs/operators';
import { Store, Select } from '@ngxs/store';
import { FavouritesState } from './state';

@Injectable({
  providedIn: 'root'
})
export class UniversityService {
  @Select(FavouritesState.getFavourites) favourites$: Observable<University[]>;

  favs: University[] = [];

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.favourites$.subscribe(f => {
      console.log('favs updated');
      this.favs = f;
    });
  }

  public getUniversities = (country: string, name: string) : Observable<University[]> => this.http
    .get<University[]>(`http://universities.hipolabs.com/search?country=${country}&name=${name}`)
    .pipe(map(this.produceUniArr));

  private produceUniArr(respData: University[]) {
    const uniArr: University[] = [];
    respData.forEach(element => {
      const uni = new University(element['state-province'], element.country, element.name, element.web_pages, element.domains, element.alpha_two_code);

      const isContains = this.favs?.filter(u => u.country === element.country && u.name === element.name).length > 0;
      console.log(isContains);
      uni.isFavourite = isContains;

      uniArr.push(uni);
    });
    return uniArr;
  }
}

线console.log(iscontains);始终在Dev Console中打印出false

此行console.log('Favs Updated');永远不会打印出来。我假设使用subscribe会导致favs变量被填充。我错误地使用了这个?

getuniversities()函数是从搜索组件中调用的:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { Observable, Subscription } from 'rxjs';
import { FavouritesState } from '../shared/state';
import { University } from '../shared/university.model';
import { UniversityService } from '../shared/university.service';
import { Results } from '../shared/results.actions';
import { Search } from '../shared/search.actions';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  @Select(FavouritesState.getFavourites) favourites$: Observable<University[]>;
  @Select(FavouritesState.getSearchResults) searchResults$: Observable<University[]>;
  @Select(FavouritesState.getCountry) country$: Observable<string>;
  @Select(FavouritesState.getSchoolName) schoolName$: Observable<string>;

  favs: University[];
  country: string;
  schoolName: string;

  constructor(private http: HttpClient, private universityService: UniversityService, private store: Store) {
  }

  ngOnInit(): void {
    this.searchResults$.subscribe(res => {
      this.favs = res;
    });
    this.country$.subscribe(c => {
      this.country = c;
    });
    this.schoolName$.subscribe(n => {
      this.schoolName = n;
    });
  }

  doAutoPost(value) {
    console.log(value,this.isLoading , this.country , this.schoolName);
    if (!this.isLoading && this.country !== '' && this.schoolName !== '') {
      this.doPost( { country: this.country, name: this.schoolName } );
    }
    else{
      console.log('not searching');
    }
  }

  isLoading: boolean = false;
  loader: Subscription;

  doPost(postData: { country: string; name: string }): void {
    this.isLoading = true;

    if (this.loader) {
      this.loader.unsubscribe();
      console.log('unsubscribed');
    }

    console.log('loading...');

    this.loader = this.universityService
      .getUniversities(postData.country, postData.name)
      .subscribe(unis => {
        console.log('loaded.');
        this.store.dispatch(new Results.Found(unis));
        this.isLoading = false;
      });
  }
}

我如何使用fairter $ array正确填充了University>大学的数组从productuniarr函数返回的对象?另外,我是否使用收藏夹$可正确观察到? this.favs应使用Universities的最爱列表进行更新。

(我当前的工作知识是, href =“ https://github.com/horacebury/favuni” rel =“ nofollow noreferrer”>在这里。

I'm trying to use an observable favourites$ when building another array of the same type. I am expecting that the favourites$ observable will be populated with the array of type Universty and that I can set a class variable to be updated with it's content. I'm doing that subscribing in the ngOnInit().

In a function of my service, I am trying to iterate over the received list of University objects and set a property isFavourite value on them if their equivalent object is found within the favourites$ observable array.

This is not working and I don't know why...

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { University } from './university.model';
import { map } from 'rxjs/operators';
import { Store, Select } from '@ngxs/store';
import { FavouritesState } from './state';

@Injectable({
  providedIn: 'root'
})
export class UniversityService {
  @Select(FavouritesState.getFavourites) favourites$: Observable<University[]>;

  favs: University[] = [];

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.favourites$.subscribe(f => {
      console.log('favs updated');
      this.favs = f;
    });
  }

  public getUniversities = (country: string, name: string) : Observable<University[]> => this.http
    .get<University[]>(`http://universities.hipolabs.com/search?country=${country}&name=${name}`)
    .pipe(map(this.produceUniArr));

  private produceUniArr(respData: University[]) {
    const uniArr: University[] = [];
    respData.forEach(element => {
      const uni = new University(element['state-province'], element.country, element.name, element.web_pages, element.domains, element.alpha_two_code);

      const isContains = this.favs?.filter(u => u.country === element.country && u.name === element.name).length > 0;
      console.log(isContains);
      uni.isFavourite = isContains;

      uniArr.push(uni);
    });
    return uniArr;
  }
}

The line console.log(isContains); always prints out false in the dev console.

This line console.log('favs updated'); never prints out. I was assuming that the use of subscribe would cause the favs variable to be populated. I am using this incorrectly?

The getUniversities() function is called from the search component:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { Observable, Subscription } from 'rxjs';
import { FavouritesState } from '../shared/state';
import { University } from '../shared/university.model';
import { UniversityService } from '../shared/university.service';
import { Results } from '../shared/results.actions';
import { Search } from '../shared/search.actions';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  @Select(FavouritesState.getFavourites) favourites$: Observable<University[]>;
  @Select(FavouritesState.getSearchResults) searchResults$: Observable<University[]>;
  @Select(FavouritesState.getCountry) country$: Observable<string>;
  @Select(FavouritesState.getSchoolName) schoolName$: Observable<string>;

  favs: University[];
  country: string;
  schoolName: string;

  constructor(private http: HttpClient, private universityService: UniversityService, private store: Store) {
  }

  ngOnInit(): void {
    this.searchResults$.subscribe(res => {
      this.favs = res;
    });
    this.country$.subscribe(c => {
      this.country = c;
    });
    this.schoolName$.subscribe(n => {
      this.schoolName = n;
    });
  }

  doAutoPost(value) {
    console.log(value,this.isLoading , this.country , this.schoolName);
    if (!this.isLoading && this.country !== '' && this.schoolName !== '') {
      this.doPost( { country: this.country, name: this.schoolName } );
    }
    else{
      console.log('not searching');
    }
  }

  isLoading: boolean = false;
  loader: Subscription;

  doPost(postData: { country: string; name: string }): void {
    this.isLoading = true;

    if (this.loader) {
      this.loader.unsubscribe();
      console.log('unsubscribed');
    }

    console.log('loading...');

    this.loader = this.universityService
      .getUniversities(postData.country, postData.name)
      .subscribe(unis => {
        console.log('loaded.');
        this.store.dispatch(new Results.Found(unis));
        this.isLoading = false;
      });
  }
}

How can I make use of the favourites$ array to correctly populate the array of University objects which are returned from the produceUniArr function? Also, am I using the favourites$ observable correctly? (My current working knowledge is that this.favs should be updated with the favourited list of Universities whenever that list changes.)

If it helps, the full source is available here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天邊彩虹 2025-01-31 13:47:31

事实证明,该服务的构造函数和ngoninit没有被调用(我不知道为什么),所以我必须将所有@select

如果有人可以解释如何完成这项工作,我将选择该帖子作为答案。

Turns out the constructor and ngOnInit of the service were not being called (I don't know why) so I had to move all the @Select and related logic out into a component.

If someone can explain how to make this work, I will select that post as the answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文