过滤 Angular/Nativescript 中的 observable [英] Filtering an observable in Angular/Nativescript

查看:24
本文介绍了过滤 Angular/Nativescript 中的 observable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在尝试构建一个应用程序来检索一个可观察对象,然后您可以以一些预定义的方式对其进行排序和/或过滤.

检索和排序数据工作正常:

sort.service.ts

import { Injectable } from "@angular/core"从@angular/common/http"导入 { HttpClient, HttpErrorResponse }import { Observable } from "rxjs/Observable";从rxjs"导入{订阅者};导入rxjs/add/operator/catch";导入rxjs/add/operator/do";导入rxjs/add/operator/map";从../property/property.model"导入{属性};从../../data/usersettings/usersettings.service"导入{ UserSettings }导出类 SortService {url = "/path/to/file.json";构造函数(私有 http:HttpClient){}getProperties(): Observable{返回 this.http.get(this.url);}sortAllProperties() {让计数 = 0;返回 this.getProperties().map((数据) => {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 + " 小于 " + this.userSettings.getAppSetting("filterMinPrice", "number"));*/const aID = a.ID;const bID = b.ID;//价格排序(初级)const priceSort = this.userSettings.getAppSetting("sortByPrice", "string");if(priceSort == "asc") {如果 (aP > bP) 返回 1;如果 (aP < bP) 返回 -1;} else if (priceSort == "desc") {如果 (aP < bP) 返回 1;如果 (aP > bP) 返回 -1;} 别的 {计数++;}//面积排序(次要)const sizeSort = this.userSettings.getAppSetting("sortBySize", "string");if(sizeSort == "asc") {如果 (aS > bS) 返回 1;如果 (aS < bS) 返回 -1;} else if (sizeSort == "desc") {if (aS < bS) 返回 1;如果 (aS > bS) 返回 -1;} 别的 {计数++;}//房间排序(三级)const roomSort = this.userSettings.getAppSetting("sortByRooms", "string");if(roomSort == "asc") {如果 (aR > bR) 返回 1;如果 (aR < br) 返回 -1;} else if (roomSort == "desc") {如果 (aR < bR) 返回 1;如果 (aR > br) 返回 -1;} 别的 {计数++;}//卧室排序(四元)const卧室排序 = this.userSettings.getAppSetting("sortByBedrooms", "string");如果(卧室排序==asc"){如果 (aB > bB) 返回 1;如果 (aB < bB) 返回 -1;} else if (bedroomSort == "desc") {如果 (aB < bB) 返回 1;如果 (aB > bB) 返回 -1;} 别的 {计数++;}如果(计数 = 4){返回 aID >出价 ?1:-1;}})返回数据;})}}

此处检索的数据如下所示:file.json

<预><代码>[{身份证":1,"description": "Lorem ipsum dolor sat amet, consectetur adipiscing ...",价格":800.25,"协议类型": "未知","streetName": "street1",房号":249,"postCode": "邮政编码","place": "新奥尔兰","状态": "状态",建设年":1999,区域大小":5540,"numberOfRooms": 545,卧室数量":21,"车库类型": "",车库容量":0},{//...}]

和 JSON 格式遵循"的属性模型如下所示...

property.model.ts

导出类属性{身份证号码;描述:字符串;价格:数量;协议类型:字符串;街道名称:字符串;房号:号码;邮政编码:字符串;地方:字符串;状态:字符串;施工年份:编号;areaSize:数量;numberOfRooms:数量;numberOfBedrooms:数量;车库类型:字符串;车库容量:数量;}

我只是使用异步管道在属性组件中显示我的数据,它工作得很好:*ngFor="let item of propertyData | async".排序也有效.这是我的过滤问题.

现在,我只是尝试在 sortAllProperties() 方法中应用静态过滤器.使其动态化并为其提供自己的类、方法等可以稍后实现.

为此也很难找到准确的信息,因为其中大部分信息已经过时,并且使用 http 而不是 httpClient,这当然略有不同.>

到目前为止,我所做的每一次尝试(都是从互联网示例中复制并稍微调整以适应我的用例)都导致错误.到目前为止,我得到的最接近的是 .filter((property) => property.price > 800) ,我尝试将其放在 .map()<之前和之后/code> 函数,两者都导致相同的错误:

<块引用>

[ts] 类型Property[]"不存在属性price".

可能是我遗漏了一些我应该在过滤前在 observable 上使用的函数?我现在真的很茫然.

提前致谢.

解决方案

在另一位程序员的帮助下,我终于找到了解决方案.像往常一样,结果很简单:

返回 this.getProperties().map(properties => properties.filter(property=> property.price > 810).sort((a: 属性, b: 属性) => {//排序东西})

这是一个过滤器.如果你想应用多个过滤器,你可能会做这样的事情

返回 this.getProperties().map(properties => properties.filter((property) => {//过滤条件,数组等归还财产;}).sort((a: 属性, b: 属性) => {//排序东西})

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;
        })
    }
}

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
  },
  {
     //...
  }
]

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;
}

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.

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.

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.

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] 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.

Thank you in advance.

解决方案

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 中的 observable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆