Там нет необходимости конвертировать наблюдаемый возвращаемый ГЮТ в HTTP() метод в обещание. В большинстве случаев служба может просто вернуть наблюдаемый.
Если мы необходимо извлечь массив или примитивного типа (то есть строка, число, булевы) с сервера, мы можем упростить нашу логику контроллера с помощью возвращаемого наблюдаемого непосредственно в нашем шаблоне, с asyncPipe , Эта труба будет автоматически подписываться на наблюдаемую (она также работает с обещанием), и она вернет самое последнее значение, которое излучает наблюдаемое. Когда выдается новое значение, канал отмечает, что компонент должен быть проверен на изменения, поэтому представление автоматически обновится с новым значением.
Если мы необходимо извлечь объект с сервера,
я не знаю ни одного способа использования asyncPipe,
мы могли бы использовать асинхронную трубу, в сочетании с безопасным оператором навигации следующим образом:
{{(objectData$ | async)?.name}}
Но это выглядит сложным, и нам нужно будет повторить это для каждого свойства объекта, которое мы хотели отобразить.
Вместо этого я предлагаю subscribe()
наблюдаемому в компоненте и сохранить содержащийся объект в свойстве компонента. Затем мы используем safe navigation operator (?.) Или (как упоминается в комментарии @Evan Plaice в комментарии) NgIf в шаблоне. Если мы не используем безопасный навигационный оператор или NgIf, ошибка будет вызываться, когда шаблон сначала попытается выполнить рендеринг, потому что объект еще не заполнен значением.
Обратите внимание, что служба внизу всегда возвращает наблюдаемый для каждого метода get.
service.ts
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map'; // we need to import this now
@Injectable()
export class MyService {
constructor(private _http:Http) {}
getArrayDataObservable() {
return this._http.get('./data/array.json')
.map(data => data.json());
}
getPrimitiveDataObservable() {
return this._http.get('./data/primitive.txt')
.map(data => data.text()); // note .text() here
}
getObjectDataObservable() {
return this._http.get('./data/object.json')
.map(data => data.json());
}
}
app.ts
import {Component} from 'angular2/core';
import {MyService} from './my-service.service';
import {HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'my-app',
providers: [HTTP_PROVIDERS, MyService],
template: `
<div>array data using '| async':
<div *ngFor="#item of arrayData$ | async">{{item}}</div>
</div>
<div>primitive data using '| async': {{primitiveData$ | async}}</div>
<div>object data using ?.: {{objectData?.name}}</div>
<div *ngIf="objectData">object data using NgIf: {{objectData.name}}</div>`
})
export class AppComponent {
constructor(private _myService:MyService) { console.clear(); }
ngOnInit() {
this.arrayData$ = this._myService.getArrayDataObservable();
this.primitiveData$ = this._myService.getPrimitiveDataObservable();
this._myService.getObjectDataObservable()
.subscribe(data => this.objectData = data);
}
}
Примечание: Я поставил "Наблюдаемая" в именах методов обслуживания – например, getArrayDataObervable()
– только подчеркнуть, что метод возвращает Observable , Обычно вы не ставите «Observable» в названии.
данные/array.json
[ 1,2,3 ]
данные/примитивными.JSON
Greetings SO friends!
данные/object.json
{ "name": "Mark" }
Выход:
array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark
Plunker
Один недостаток Usin g труба async
заключается в том, что нет механизма для обработки ошибок сервера в компоненте. I answered another question, который объясняет, как поймать такие ошибки в компоненте, но в этом случае нам всегда нужно использовать subscribe()
.
Вы ** можете ** использовать HTTP в качестве обещания, добавив '.toPromise()', за которым следует цепочка '.then()' вызовов. Тем не менее, наблюдаемые являются рекомендуемым подходом. –
@EvanPlaice Да, я прочитал о них, и теперь я поклонник Observables :) –
посмотрите на это http://stackoverflow.com/a/34758630/5043867 –