过滤Angular/Nativescript中的可观察对象 [英] Filtering an observable in Angular/Nativescript

查看:106
本文介绍了过滤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屋!

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