2016-05-13 5 views
5

Я новичок в Angular 2 и Observables, поэтому прошу прощения, если моя проблема тривиальна. Во всяком случае, я пытаюсь протестировать HTTP-клиент Angular 2 с помощью RxJS. Хотя я получил его на работу, мне нужно добавить больше логики к сервису, над которым я сейчас работаю. В принципе, я хотел бы иметь функцию сопоставления для преобразования объекта, который я получаю из веб-службы, к которой я подключен, к объекту модели, который у меня есть в Angular.Angular2 RxJS вызов функции класса из функции карты

Это код, который работает:

import { Injectable } from 'angular2/core'; 
import { Http, Response } from 'angular2/http'; 
import { Observable } from 'rxjs/Observable'; 

import { Person } from '../models/person'; 

@Injectable() 
export class PersonsService { 

    constructor(private http: Http) { } 

    private personsUrl = 'http://localhost/api/persons'; 

    getPersons(): Observable<Person[]> { 
     return this.http.get(this.personsUrl) 
      .map(this.extractData) 
      .catch(this.handleError); 
    } 

    private extractData(res: Response) { 
     if(res.status < 200 || res.status >= 300) { 
      throw new Error('Bad response status ' + res.status); 
     } 

     let body = res.json(); 
     return body.data || {}; 
    } 

    private handleError(error: any) { 
     let errMsg = error.message; 
     return Observable.throw(errMsg); 
    } 
} 

С выше коде я не имею никаких проблем. Проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы отобразить объект, который я получаю от службы, к той, которая у меня есть в Angular i.e Person. Я попытался вызвать другую функцию из функции extractData, которая используется функцией .map.

private extractData(res: Response) { 
    if(res.status < 200 || res.status >= 300) { 
     throw new Error('Bad response status ' + res.status); 
    } 

    let body = res.json(); 
    // map data function 
    var data = this.mapData(body.data); 

    return data || {}; 
} 

private mapData(data: any) { 
    // code to map data 
} 

Очевидно, что приведенный выше код не работает, когда this ссылается внутри функции extractData, this не относится к классу PersonsService, но это относится к MapSubscriber объекта.

Я не знаю, можно ли вызвать «внешнюю» функцию. Это может быть глупо, но я не могу найти никакой информации об этом.

ответ

17

Вместо того, чтобы просто Проходя мимо function использования системными arrow функции сохранить this

.map((res) => this.extractData(res)) 
+0

Отлично! Большое спасибо :) Не могли бы вы объяснить причины этого? –

+2

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions без него 'this' будет указывать на функцию, в которой выполняется вызов. –

+0

Я вытягивал свои волосы из-за этого. Благодаря! –

2

На самом деле функция карты Observable позволяет Вам передавать ссылочную переменную в качестве второго аргумента о том, как следует this фактически работать внутри высшего порядка функция.
поэтому решения является
.map(this.extractData,this)
Таким образом, при прохождении функции extractData вы также проходящую контекст this выполнения текущего класса к функции высшего порядка. Он будет работать.

Observable Doc Reference Link

screenshot of the doc

Смежные вопросы