过滤Angular/Nativescript中的可观察对象 [英] Filtering an observable in Angular/Nativescript
问题描述
当前,我正在尝试构建一个应用程序来检索可观察对象,然后您可以使用一些预定义的方式对其进行排序和/或过滤.
Currently, I'm trying to build an app which retrieves an obserable, which you can then sort and/or filter in some predefined ways.
检索和排序数据可以正常工作:
Retrieving and sorting the data works fine:
sort.service.ts
import { Injectable } from "@angular/core"
import { HttpClient, HttpErrorResponse } from "@angular/common/http"
import { Observable } from "rxjs/Observable";
import { Subscriber } from "rxjs";
import "rxjs/add/operator/catch";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";
import { Property } from "../property/property.model";
import { UserSettings } from "../../data/usersettings/usersettings.service"
export class SortService {
url = "/path/to/file.json";
constructor(private http:HttpClient) {}
getProperties(): Observable<Property[]> {
return this.http.get<Property[]>(this.url);
}
sortAllProperties() {
let count = 0;
return this.getProperties()
.map((data) => {
data.sort((a: Property, b: Property) => {
const aP = a.price;
const bP = b.price;
const aS = a.areaSize;
const bS = b.areaSize;
const aR = a.numberOfRooms;
const bR = b.numberOfRooms;
const aB = a.numberOfBedrooms;
const bB = b.numberOfBedrooms;
/*if(this.userSettings.getAppSetting("filterMinPrice", "number") >= a.price)
console.log(a.price + " is smaller than " + this.userSettings.getAppSetting("filterMinPrice", "number"));*/
const aID = a.ID;
const bID = b.ID;
//Price sort (primary)
const priceSort = this.userSettings.getAppSetting("sortByPrice", "string");
if(priceSort == "asc") {
if (aP > bP) return 1;
if (aP < bP) return -1;
} else if (priceSort == "desc") {
if (aP < bP) return 1;
if (aP > bP) return -1;
} else {
count++;
}
//Areasize sort (secondary)
const sizeSort = this.userSettings.getAppSetting("sortBySize", "string");
if(sizeSort == "asc") {
if (aS > bS) return 1;
if (aS < bS) return -1;
} else if (sizeSort == "desc") {
if (aS < bS) return 1;
if (aS > bS) return -1;
} else {
count++;
}
//Rooms sort (tertiary)
const roomSort = this.userSettings.getAppSetting("sortByRooms", "string");
if(roomSort == "asc") {
if (aR > bR) return 1;
if (aR < bR) return -1;
} else if (roomSort == "desc") {
if (aR < bR) return 1;
if (aR > bR) return -1;
} else {
count++;
}
//Bedrooms sort (quaternary)
const bedroomSort = this.userSettings.getAppSetting("sortByBedrooms", "string");
if(bedroomSort == "asc") {
if (aB > bB) return 1;
if (aB < bB) return -1;
} else if (bedroomSort == "desc") {
if (aB < bB) return 1;
if (aB > bB) return -1;
} else {
count++;
}
if(count = 4) {
return aID > bID ? 1 : -1;
}
})
return data;
})
}
}
此处要检索的数据如下所示: file.json
The data being retrieved here, looks like this: file.json
[
{
"ID": 1,
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing ...",
"price": 800.25,
"agreementType": "unknown",
"streetName": "street1",
"houseNumber": 249,
"postCode": "postcode",
"place": "New Orlands",
"status": "status",
"constructionYear": 1999,
"areaSize": 5540,
"numberOfRooms": 545,
"numberOfBedrooms": 21,
"garageType": "",
"garageCapacity": 0
},
{
//...
}
]
和JSON格式遵循"的属性模型如下所示……
and the property model, which the JSON format "adheres" to, looks as follows...
property.model.ts
export class Property {
ID: number;
description: string;
price: number;
agreementType: string;
streetName: string;
houseNumber: number;
postCode: string;
place: string;
status: string;
constructionYear: number;
areaSize: number;
numberOfRooms: number;
numberOfBedrooms: number;
garageType: string;
garageCapacity: number;
}
我仅使用异步管道在属性组件中显示数据,该管道工作得很好:*ngFor="let item of propertyData | async"
.排序也可以.这是我遇到问题的过滤条件.
I'm displaying my data in the property component simply using an async pipe, which works just fine: *ngFor="let item of propertyData | async"
. The sorting works as well. It's the filtering I have an issue with.
现在,我只是尝试在sortAllProperties()
方法内部应用静态过滤器.使其动态化并为其提供自己的类,方法等会在以后出现.
For now, I'm simply trying to apply a static filter inside the sortAllProperties()
method. Making it dynamic and giving it its own class, methods etc can come later.
为此也很难找到正确的信息,因为大多数信息已经过时并且使用http
而不是httpClient
,这当然有些不同.
It's also hard finding the exact right information for this, because most of it is outdated and uses http
rather than httpClient
, which is of course slighty different.
到目前为止,我所做的每一次尝试(均从互联网示例中复制并进行了微调以适合我的用例)均导致错误.到目前为止,我得到的最接近的是.filter((property) => property.price > 800)
,我尝试将其放置在.map()
函数的前面,之后又放置在.map()
函数的后面,两者都会导致相同的错误:
Every attempt I've made so far (all copied from internet examples and slightly adjusted to fit my use-case) resulted in an error. The closest I got so far is .filter((property) => property.price > 800)
which I tried placing in front of, and later after the .map()
function, both resulting in the same error:
[ts]属性"price"在类型"Property []"上不存在.
[ts] Property 'price' does not exist on type 'Property[]'.
是否可能是我缺少一些在过滤之前应该在可观察对象上使用的功能?我现在真的很茫然.
Could it be that I'm missing some functions I should use on the observable before filtering? I'm really at a loss right now.
谢谢.
推荐答案
在另一个程序员的帮助下,我终于设法获得了解决方案.像往常一样,结果非常简单:
With the help of another programmer, I finally managed to get the solution. As usual, it turned out to be pretty simple:
return this.getProperties()
.map(properties => properties.filter(property=> property.price > 810)
.sort((a: Property, b: Property) => {
//sorting stuff
})
用于一个过滤器.如果您想应用多个过滤器,则可以执行类似的操作
That's for one filter. If you want to apply multiple filters, you could probably do something like
return this.getProperties()
.map(properties => properties.filter((property) => {
//filter coniditions, arrays etc
return property;
})
.sort((a: Property, b: Property) => {
//sorting stuff
})
这篇关于过滤Angular/Nativescript中的可观察对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!