在 Angular/Nativescript 中过滤 observable

Posted

技术标签:

【中文标题】在 Angular/Nativescript 中过滤 observable【英文标题】:Filtering an observable in Angular/Nativescript 【发布时间】:2018-07-15 22:33:23 【问题描述】:

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

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

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

[
  
    "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 格式“遵循”的属性模型如下...

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"。排序也有效。这是我遇到问题的过滤器。

目前,我只是尝试在 sortAllProperties() 方法中应用静态过滤器。让它动态化并赋予它自己的类、方法等可以稍后实现。

也很难找到确切的正确信息,因为其中大部分都已过时并且使用http 而不是httpClient,这当然略有不同。

到目前为止,我所做的每一次尝试(全部从互联网示例中复制并稍作调整以适合我的用例)都会导致错误。到目前为止,我得到的最接近的是 .filter((property) =&gt; property.price &gt; 800),我尝试将它放在前面,然后在 .map() 函数之后,两者都导致相同的错误:

[ts] 类型“Property[]”上不存在属性“price”。

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

提前谢谢你。

【问题讨论】:

【参考方案1】:

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

return this.getProperties()
.map(properties => properties.filter(property=> property.price > 810)
.sort((a: Property, b: Property) => 
   //sorting stuff
)

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

return this.getProperties()
.map(properties => properties.filter((property) => 
   //filter coniditions, arrays etc
   return property;
)
.sort((a: Property, b: Property) => 
   //sorting stuff
)

【讨论】:

以上是关于在 Angular/Nativescript 中过滤 observable的主要内容,如果未能解决你的问题,请参考以下文章

在 Nativescript App 中调整从 URL 接收到的图像大小时出错

VUE中过了一遍还不熟悉的东西

kettle 怎样从转换中过的job中定义的变量

机器学习中过拟合欠拟合与方差偏差的关系是什么?

宅在家中过,钱从天上来!

pytorch-模型训练中过拟合和欠拟合问题。从模型复杂度和数据集大小排查问题