Angular2 http.get(), map(), subscribe() и наблюдаемый шаблон - базовое понимание
Теперь у меня есть начальная страница, где у меня есть три ссылки. После того, как вы нажмете на последнюю ссылку "друзья", начнут инициироваться соответствующие друзья. Там,
Я хочу получить/получить список моих друзей в файле friends.json.
До сих пор все работает нормально. Но я все еще новичок в сервисе angular2 HTTP, используя RxJs, наблюдаемые, отображающие карту, подписку. Я попытался понять это и прочитать несколько статей, но пока я не получу практическую работу, я не буду правильно понимать эти понятия.
Здесь я уже сделал plnkr, который работает, кроме работы, связанной с HTTP.
Plnkr
myfriends.ts
import {Component,View,CORE_DIRECTIVES} from 'angular2/core';
import {Http, Response,HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/Rx';
@Component({
template: `
<h1>My Friends</h1>
<ul>
<li *ngFor="#frnd of result">
{{frnd.name}} is {{frnd.age}} years old.
</li>
</ul>
`,
directive:[CORE_DIRECTIVES]
})
export class FriendsList{
result:Array<Object>;
constructor(http: Http) {
console.log("Friends are being called");
// below code is new for me. So please show me correct way how to do it and please explain about .map and .subscribe functions and observable pattern.
this.result = http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result =result.json());
//Note : I want to fetch data into result object and display it through ngFor.
}
}
Пожалуйста, объясните правильно и объясните. Я знаю, что это будет очень полезно для многих новых разработчиков.
Ответы
Ответ 1
Вот где вы поступили не так:
this.result = http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result =result.json());
это должно быть:
http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result =result);
или
http.get('friends.json')
.subscribe(result => this.result =result.json());
Вы допустили две ошибки:
1- Вы назначили наблюдаемое значение this.result
. Когда вы действительно хотели назначить список друзей this.result
. Правильный способ сделать это:
-
вы подписываетесь на наблюдаемое. .subscribe
- это функция, которая фактически выполняет наблюдаемое. Требуется три параметра обратного вызова:
.subscribe(success, failure, complete);
например:
.subscribe(
function(response) { console.log("Success Response" + response)},
function(error) { console.log("Error happened" + error)},
function() { console.log("the subscription is completed")}
);
Обычно вы берете результаты от обратного вызова успеха и назначаете его переменной.
обратный вызов ошибки сам по себе.
полный обратный вызов используется для определения того, что вы получили последние результаты без каких-либо ошибок.
На вашем плунтере, полный обратный вызов будет всегда вызываться после успешного или обратного вызова.Забастовкa >
2- Вторая ошибка, вы назвали .json()
на .map(res => res.json())
, после чего вы снова вызвали ее на обратном вызове успеха наблюдаемого.
.map()
- это трансформатор, который преобразует результат в то, что вы возвращаете (в вашем случае .json()
), прежде чем он перейдет на обратный вызов успеха
вы должны называть его один раз на одном из них.
Ответ 2
Основные понятия
Наблюдаемые в коротких задачах асинхронная обработка и события. По сравнению с promises это можно описать как наблюдаемые = promises + события.
Что отлично с наблюдаемыми, так это то, что они ленивы, их можно отменить, и вы можете применить к ним некоторые операторы (например, map
,...). Это позволяет обрабатывать асинхронные вещи очень гибким способом.
Отличный пример, описывающий наилучшую силу наблюдаемых, - это способ подключения входа фильтра к соответствующему отфильтрованному списку. Когда пользователь вводит символы, список обновляется. Наблюдаемые обрабатывают соответствующие запросы AJAX и отменяют предыдущие запросы на выполнение, если другое инициируется новым значением на входе. Вот соответствующий код:
this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
(textValue
- это элемент управления, связанный с входом фильтра).
Вот более подробное описание такого варианта использования: Как посмотреть изменения формы в Angular 2?.
В AngularConnect 2015 и EggHead есть две отличные презентации:
Кристоф Бургдорф также написал несколько замечательных постов в блоге по теме:
В действии
На самом деле в отношении вашего кода вы смешивали два подхода:-) Вот они:
-
Управлять наблюдаемым вашим собственным. В этом случае вы отвечаете за вызов метода subscribe
для наблюдаемого и присваиваете результат атрибуту компонента. Затем вы можете использовать этот атрибут в представлении для итерации по коллекции:
@Component({
template: `
<h1>My Friends</h1>
<ul>
<li *ngFor="#frnd of result">
{{frnd.name}} is {{frnd.age}} years old.
</li>
</ul>
`,
directive:[CORE_DIRECTIVES]
})
export class FriendsList implement OnInit, OnDestroy {
result:Array<Object>;
constructor(http: Http) {
}
ngOnInit() {
this.friendsObservable = http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result = result);
}
ngOnDestroy() {
this.friendsObservable.dispose();
}
}
Возврат из методов get
и map
является наблюдаемым не результатом (таким же образом, как с promises).
-
Позвольте управлять наблюдаемым шаблоном Angular. Вы также можете использовать канал async
для неявного управления наблюдаемым. В этом случае нет необходимости явно вызывать метод subscribe
.
@Component({
template: `
<h1>My Friends</h1>
<ul>
<li *ngFor="#frnd of (result | async)">
{{frnd.name}} is {{frnd.age}} years old.
</li>
</ul>
`,
directive:[CORE_DIRECTIVES]
})
export class FriendsList implement OnInit {
result:Array<Object>;
constructor(http: Http) {
}
ngOnInit() {
this.result = http.get('friends.json')
.map(response => response.json());
}
}
Вы можете заметить, что наблюдаемые ленивы. Таким образом, соответствующий HTTP-запрос будет вызываться только после прослушивателя с прикрепленным к нему с помощью метода subscribe
.
Вы также можете заметить, что метод map
используется для извлечения содержимого JSON из ответа и использования его в наблюдаемой обработке.
Надеюсь, это поможет вам,
Thierry
Ответ 3
import { HttpClientModule } from '@angular/common/http';
API HttpClient был представлен в версии 4.3.0. Это эволюция существующего HTTP API и имеет собственный пакет @angular/common/http.
Одним из наиболее заметных изменений является то, что теперь объектом ответа является JSON по умолчанию, поэтому нет необходимости разбирать его с помощью метода карты. Вплоть отсюда мы можем использовать, как показано ниже
http.get('friends.json').subscribe(result => this.result =result);