如何使用一个可观察的一个来更新另一个
我正在尝试使用可观察的收藏夹$
构建同一类型的其他数组时。我期望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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,该服务的构造函数和
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.