Prosty filtr na tablicy Rxjs obserwowalny
Zaczynam swój projekt od Angular2 i deweloperzy wydają się polecać Rxjs Observable zamiast obietnic.
Udało mi się pobrać listę elementów (epic) z serwera. Ale jak mogę filtrować elments używając na przykład id?
Poniższy kod jest ekstrakcją z mojej aplikacji i pokazuje teraz ostateczne rozwiązanie robocze. Miejmy nadzieję, że to komuś pomoże.
@Injectable()
export class EpicService {
private url = CONFIG.SERVER + '/app/'; // URL to web API
constructor(private http:Http) {}
private extractData(res:Response) {
let body = res.json();
return body;
}
getEpics():Observable<Epic[]> {
return this.http.get(this.url + "getEpics")
.map(this.extractData)
.catch(this.handleError);
}
getEpic(id:string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
}
export class EpicComponent {
errorMessage:string;
epics:Epic[];
epic:Epic;
constructor(
private requirementService:EpicService) {
}
getEpics() {
this.requirementService.getEpics()
.subscribe(
epics => this.epics = epics,
error => this.errorMessage = <any>error);
}
// actually this should be eventually in another component
getEpic(id:string) {
this.requirementService.getEpic(id)
.subscribe(
epic => this.epic = epic,
error => this.errorMessage = <any>error);
}
}
export class Epic {
id: string;
name: string;
}
Z góry dziękuję za pomoc. 4 answers
Będziesz chciał filtrować rzeczywistą tablicę, a nie obserwowalną owiniętą wokół niej.
Więc zmapujesz zawartość Obserwowalnej (która jest Epic[]
) na filtrowaną Epic
.
getEpic(id:number): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
Potem możesz subscribe
do getEpic
i robić z tym, co chcesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 12:42:58
Możesz to zrobić używając metod flatMap
i filter
Observable
zamiast metody js array filter w map
. Coś w stylu:
this.getEpics()
.flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
.filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe((result) => ...); // do something epic!!!
flatMap
zapewni pojedyncze wskaźniki do filtrowania, a następnie możesz przejść do tego, co dzieje się dalej z wynikami.
Jeśli TypeScript wyświetli błąd wskazujący, że nie możesz porównać ciągu znaków i liczby niezależnie od użycia ==
w filtrze, po prostu dodaj +
przed epic.id
w filtrze, na kąt docs:
.flatMap(...)
.filter((epic) => +epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe(...)
Przykład:
Https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 17:58:37
Observables
są leniwi. Musisz zadzwonić subscribe
, aby powiedzieć observable
, Aby wysłać swoją prośbę.
getEpic(id:number) {
return this.getEpics()
.subscribe(x=>...)
.filter(epic => epic.id === id);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 12:42:46
Musisz zapisać się na Observable
s, aby uzyskać dane, ponieważ połączenia http są asynchroniczne w JavaScript.
getEpic(id: number, callback: (epic: Epic) => void) {
this.getEpics().subscribe(
epics: Array<Epic> => {
let epic: Epic = epics.filter(epic => epic.id === id)[0];
callback(epic);
}
);
}
Możesz wywołać tę metodę w następujący sposób:
this.someService.getEpic(epicId, (epic: Epic) => {
// do something with it
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 12:43:07