【发布时间】:2019-08-15 22:52:47
【问题描述】:
我正在学习 observables atm,我有一个问题。我从我的后端 api 得到一个 json 数组并将它放在一个 Observable 中(其中图像是我自己定义的模型)。现在这些都是图像,但我只想要那些名称以 display 开头的图像。我已经尝试了一些事情,但我找不到解决方案。这就是我目前所得到的。
get images$(): Observable<Image[]> {
return this._fetchImages$
.pipe(
filter(i => i.filter(img => img.name.toLowerCase().startsWith("display")))
);
}
这给出:
Type 'Image[]' is not assignable to type 'boolean'.ts(2322)
filter.d.ts(3, 46): The expected type comes from the return type of this signature.
图像模型类
export class Image {
constructor(
private _name: string,
private _iso: string,
private _shutter: string,
private _aperture: string,
private _country: string,
private _likes: number,
private _content: string
) {}
get name(): string {
return this._name;
}
get iso(): string {
return this._iso;
}
get shutter(): string {
return this._shutter;
}
get aperture(): string {
return this._aperture;
}
get country(): string {
return this._country;
}
get likes(): number {
return this._likes;
}
get content(): string {
return this._content;
}
set likes(value: number) {
this._likes = value;
}
static fromJson(json: any): Image {
return new Image(
json.name,
json.iso,
json.shutterSpeed,
json.aperture,
json.country,
json.likes,
json.content
);
}
}
为我提供价值的服务
export class ImageDataService {
constructor(private http: HttpClient) {}
get images$(): Observable<Image[]> {
return this.http
.get(`${environment.apiUrl}/images/`)
.pipe(map((list: any[]): Image[] => list.map(Image.fromJson)));
}
}
请求 observable 的组件
export class GridComponent implements OnInit {
public countryFilter: string;
public filterImage$ = new Subject<string>();
private _fetchImages$: Observable<Image[]> = this._imageDataService.images$;
constructor(private _imageDataService: ImageDataService) {
this.filterImage$
.pipe(
distinctUntilChanged(),
debounceTime(400),
map(val => val.toLowerCase())
)
.subscribe(val => (this.countryFilter = val));
}
get images$(): Observable<Image[]> {
return this._fetchImages$.pipe(
map(i => i.filter(img => img.name.toLowerCase().startsWith('display')))
);
}
ngOnInit() {}
}
<div>
<mat-form-field>
<input matInput placeholder="Country" type="text" #countryName (keyup)="filterImage$.next($event.target.value)"
class="browser-default">
</mat-form-field>
<mat-grid-list cols="3" gutterSize=" 5px" rowHeight="500px">
<mat-grid-tile *ngFor="let image of (images$ | async)">
<app-image [image]="image"></app-image>
</mat-grid-tile>
</mat-grid-list>
</div>
export class ImageComponent implements OnInit {
private _icon: string;
@Input('image') public image: Image;
constructor() {
this._icon = 'favorite_border';
}
ngOnInit() {}
like() {
if (this._icon === 'favorite_border') {
this._icon = 'favorite';
this.likes++;
} else {
this._icon = 'favorite_border';
this.image.likes--;
}
console.log(this._icon);
}
get icon(): string {
return this._icon;
}
set icon(value: string) {
this._icon = value;
}
get iso(): string {
return this.image.iso;
}
get aperture(): string {
return this.image.aperture;
}
get shutterspeed(): string {
return this.image.shutter;
}
get country(): string {
return this.image.country;
}
get name(): string {
return this.image.name;
}
get content(): string {
return this.image.content;
}
get likes(): number {
return this.image.likes;
}
set likes(value: number) {
this.image.likes = value;
}
}
我收到了 10 个 json 对象发送给我:
{
"id": 1,
"name": "Header",
"iso": "ISO-200",
"shutterSpeed": "1/80 sec",
"aperture": "f/5.6",
"country": "Belgium",
"content": //a base64 string
}
{
"id": 2,
"name": "Parallax1",
"iso": "ISO-100",
"shutterSpeed": "1/200 sec",
"aperture": "f/10",
"country": "Italy",
"content": another base64 string
}
{
"id": 5,
"name": "Display1",
"iso": "ISO-100",
"shutterSpeed": "1/200 sec",
"aperture": "f/10",
"country": "Italy",
"content": another base64 string
}
现在图像之间的主要区别是名称: 我有 1 个标题、3 个视差和 6 个显示图像。我现在想过滤我只得到显示图像的原因。基本上:10张图片进来--->6张出来
亲切的问候
【问题讨论】:
-
您希望将 observable 发出的每个事件(事件是一个数组)转换为不同的事件(过滤后的数组)。所以你需要使用
map操作符,而不是filter操作符。 -
@JBNizet 我尝试过使用地图,但是当我这样做时,显示 0 张图片
-
使用错误的运算符不会修复您的错误。它只会使情况变得更糟或不同。发布一个完整的最小示例来重现问题。
-
如果没有图片显示,那么很可能是图片组件的模板有问题。也就是说,你有很多无用的样板。图像组件中的所有吸气剂都是无用的,因为无论如何您都会暴露图像。 Image 类可以替换为一个简单的接口,并且不需要 map()。 images$ getter 在每次更改检测时重新创建一个新的 observable。
标签: arrays angular rxjs angular-httpclient