[英]Angular 2 - http.get never being call
我正在學習Angular 4,遇到了一個我似乎找不到解決方案的問題。 這里是上下文:我有一個簡單的應用程序,顯示有關美國總統的信息。 后端是webapi提供的rest API ...效果很好。 前端是一個Angular應用程序。
我將問題簡化為3個組件,1個數據服務和1個模型。 這是模型:
export class President {
constructor(
public id: number,
public presidentName: string,
public presidentNumber: number,
public yearsServed: string,
public partyAffiliation: string,
public spouse: string) {}
}
這三個組件是1. SearchComponent 2. HomeComponent 3. PresidentComponent
當應用程序啟動時,它將加載ApplicationComponent-它是根組件:
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<search-component></search-component>
<home-component></home-component>
`
})
export class ApplicationComponent {}
PresidentComponent是HomeComponent的子組件。 加載home組件時,它將對api進行http調用以獲取總裁列表,並為返回的每一行呈現1 PresidentComponent。 這很好。
我想做的是實現一個搜索功能,其中dataService公開一個EventEmitter並提供搜索方法,如下所示:
import { Injectable, EventEmitter, Output } from '@angular/core'
import { President } from '../models/President'
import { Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class DataService {
constructor(private http: Http) {
}
searchEvent: EventEmitter<any> = new EventEmitter();
// simple property for the url to the api
get presidentUrl {
return "http://localhost:51330/api/presidents";
}
search(params: any): Observable<President[]> {
let encParams = encodeParams(params);
console.log(encParams);
return this.http
.get(this.presidentUrl, {search: encParams})
.map(response => response.json());
}
getParties(): String[] {
return ['Republican', 'Democrat', 'Federalist', 'Whig', 'Democratic-Republican', 'None'];
}
getPresidents(): Observable<President[]> {
return this.http.get(this.presidentUrl)
.map(response => response.json());
}
}
/**
* Encodes the object into a valid query string.
* this function is from the book Angular2 Development with TypeScript
*/
function encodeParams(params: any): URLSearchParams {
return Object.keys(params)
.filter(key => params[key])
.reduce((accum: URLSearchParams, key: string) => {
accum.append(key, params[key]);
return accum;
}, new URLSearchParams());
}
搜索組件包含搜索表單,當單擊搜索按鈕時,它將執行onSearch()函數並在數據服務上發出調用:
onSearch(){
if(this.formModel.valid){
console.log('emitting event from search.ts');
this.dataService.searchEvent.emit(this.formModel.value);
}
}
然后,在HomeComponent中,我想訂閱此事件,並在觸發時通過dataservice執行搜索:
ngOnInit(): void {
//when component loads, get list of presidents
this.dataService.getPresidents()
.subscribe(
presidents => {
console.log('sub');
this.presidents = presidents;
},
error => console.error(error)
)
//when search event is fired, do a search
this.dataService.searchEvent
.subscribe(
params => {
console.log('in home.ts subscribe ' + JSON.stringify(params));
this.result = this.dataService.search(params);
},
err => console.log("cant get presidents. error code: %s, URL: %s"),
() => console.log('done')
);
}
當我在瀏覽器中運行此命令時,除http調用外,其他所有功能都不會執行。 如果我對dataservice本身中的http.get調用執行subscription(),它將執行,但是為什么要在HomeComponent上設置訂閱時為什么要這樣做呢? 我想在HomeComponent中處理Observable,並根據搜索結果更新UI中顯示的行長列表。 任何意見是極大的贊賞。
在服務中使用EventEmitter的整個想法是不正確的。 EventEmitter應該與@Output屬性一起使用,以將數據從子組件發送到其父組件。
即使EventEmitter是Subject的子類,您也不應該在服務中使用它。 因此,將服務注入您的組件,訂閱其在組件中的可觀察對象,並在需要時使用EventEmitter向父組件發出事件。
在代碼中this.result = this.dataService.search(params);
,結果是可觀察的。 您尚未訂閱。
在這種情況下,您應該使用async
管道來顯示數據。
為什么不使用rxjs
Subject
。 這是我的建議:
數據服務:
import { Observable, Subject } from "rxjs";
import 'rxjs/add/operator/catch';
@Injectable()
export class DataService {
private _dataSubject = new Subject();
constructor(private http: Http) {
this.http.get(this.presidentUrl)
.map(response => this._dataSubject.next(response.json()))
.catch(err => this._dataSubject.error(err));
);
}
// simple property for the url to the api
get presidentUrl {
return "http://localhost:51330/api/presidents";
}
search(params: any){
let encParams = encodeParams(params);
console.log(encParams);
this.http
.get(this.presidentUrl, {search: encParams})
.map(response => this._dataSubject.next(response.json()))
.catch(err => this._dataSubject.error(err));
}
getParties(): String[] {
return ['Republican', 'Democrat', 'Federalist', 'Whig', 'Democratic-Republican', 'None'];
}
getPresidents(): Observable<President[]> {
return this._dataSubject;
}
SearchComponent:
onSearch(){
if(this.formModel.valid){
console.log('emitting event from search.ts');
this.dataService.search(this.formModel.value);
}
}
通過這些修改,您應該只能在homeCompoent中只有1個訂閱者,然后每次調用onSearch()
時onSearch()
獲取發出的新數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.