我的服务有以下方法:
public GetCaseData(){
const url = environment.api_url;
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.get(url, { headers: headers })
.map(response => {
return response.json();
});
}
在我的app.component.ts中,我这样称呼它:
constructor(private _caseService : CaseService) {}
ngOnInit(): void {
this._caseService.GetCaseData().subscribe(data => {
this._caseService.caseData = data;
});
}
我想将this._caseService.caseData
分享给我的其他组件Home
和Contact
,但在这些组件的OnInit中,this._caseService.caseData未定义。
这里是家庭,例如,
constructor(private _caseService: CaseService) { }
ngOnInit() {
console.log(this._caseService.caseData); //is undefined here because it
// is called before the data comes back
}
我知道原因(因为组件在数据恢复之前已初始化),但我不确定如何修复它?
我把一个吸气剂放在家里,我看到了数据。在返回数据后,生命周期中是否会调用getter:
ngOnInit() {
this.data = this._caseService.caseData;
console.log('this.data ', this.data) //undefined
}
get caseData()
{
return this._caseService.caseData; //data rendered on html page
}
当我执行以下操作时,它表示希望:
代替data.
它还会抱怨,
关闭ngOnInit
}
}}
ngOnInit(){ this.concatCaseData $ = this._caseService.caseData $ .map(data => { return {data.OfficialCaseName} }
}
答案 0 :(得分:2)
要添加Elseo答案,Getter会解决您的问题,因为它一直被调用。
另一种替代方案,我认为是更好的解决方案,是使用BehaviorSubject。你可以给它一个初始状态并订阅它。
例如,您的160301002a0200002603015a5f5e17f78944857a7c58166f62f874063ace76daf1225b4dec0b3b586eb953000035001603010c800b000c7c000c790005b8308205b43082039c020101300d06092a864886f70d0101050500308198310b3009060355040613025541310d300b060355040813044b696576310d300b060355040713044b69657631143012060355040a130b43727974656b20476d624831153013060355040b130c546563686f7073205465616d311730150603550403130e7777772e63727974656b2e636f6d3125302306092a864886f70d0109011616616c6578616e6465726b6f4063727974656b2e636f6d301e170d3135313031353139343331395a170d3335313031303139343331395a3081a6310b3009060355040613025541310d300b060355040813044b696576310d300b060355040713044b696576311e301c060355040a141543727974656b20476d6248207c205761726661636531153013060355040b130c546563686f7073205465616d311b301906035504031312776172666163652e63727974656b2e636f6d3125302306092a864886f70d0109011616616c6578616e6465726b6f4063727974656b2e636f6d30820222300d06092a864886f70d01010105000382020f003082020a0282020100a7cd8444bdbd68abca318cc50a94fda5cee4954d109d324d7607d68ef3d1d9b78f0714582a9fca42c043f6348450a96e55831ade93cf6d00faf234b0a84e9390a83b73716d9c498f4882ed039ba04e969bed87bd0e5539f5e5f4a5a8c7a86b9f868361d38727a70d9c1e8a42a6851c8744eac0e83f081eeb18a11a4738e18ccd1ae1094971c0e8e84efa4e116e8a7ae22faa88eaf4b5484c5734fc2b4ce097f5782ef371ce3f33d83b503e9d8a37abe8e76641b923bdaaacd65f399d36a9edeef420de58b29088972d048f1fb9e57807ffb842d49ec93aa61539dfd3c3bd676790207bb2a2ec8078c3f12bb5d38d755ad691135b00304c73a8983c6133f2602f9497c3e0a6fe5d34d379550728184b878714c2d9e775a27b6025003e1e9644d38a0f63cfa0acb082d38383c95a93668e37bb8dadafc0a831e2e390d2d7b1c40b6daf552a7cef87e586123333584b1862eb1a762755e1ec6ff9bea52eb12881462ac1a497b0f8f9ed96220b005e5696f28461c20f9dab148cee03737e7842ceeccb8a626f504f286ae6de90889d91404a87838528f8defc2fcb00b78fcf8a1157d8164b3d4d5de716d5498bafa41c53f6500fd2dfe057519fa9e4bdede2b0c9d2a95e4706866b020bbdf79505fad53a199ea3facfbcfcbbe9459688bf83123c8f902e4002fa828fe3e59156c99a81041d62e0b362af381624d50272ce7c3c056d0203010001300d06092a864886f70d010105050003820201001a337ddb2ab892bf01008234fe8733cef1741d17172aa1a3f99346809144901d68d9b53e67d5a56c247d614fc8408e2cde98ee8564ccb821534d8796d083a2e4556def2e35cbf7e2b34edcf1b0154ce715c4f47cfa8d7e1b92d359816b4819ba08d3cb124afe8ab742c31927e5e160c54a50824abf26fe7ae65532381346bd234cf1ee5e7cd1a746cb4770dac66071adfc7c3951f2d2627b612bf7608632c5b89848d64b54513b96942234d4d9266ce28b729da9b2d7df9fd791f6fe5f0da2398a9a5fa1efe9856633f62e4beb3e76a94b2c6ece93426f33078bd97c4a582b42948fe921e87af4e7638de8bfb3329f9680595ffc59b35b9777fa2c8a045850e4af2d90e44a72c426d4d98e964d02bb0554cd341a9f33fd402b5c6021ca952ef9c7b14acf5d683989066c2400455fda8064bd67acdc516f6da29de79fef8cb2fc0aefd03b47ab7380a77abca0e097661e02ffa7c1b069118f94c7a0873edd2e0faf653dee67ace0a9e5ad4837545b677c8a2a74c445771d6da38c4b6a04274808635f9af6dcfaacc5b89c77e85cef4caaa0010da7fc010419209f2f465acd46de3e177d473d00d8524d627db6baf6359a5001
:
CaseService
在您的应用程序组件上,您将调用private caseDataStore = new BehaviorSubject<any>({});
public caseData$ = this.caseDataStore.asObservable();
public GetCaseData(){
const url = environment.api_url;
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.get(url, { headers: headers })
.map(response => {
return response.json();
}).toPromise().then(res => {
caseDataStore.next(res);
});
}
来触发其余呼叫并订阅该主题。
GetCaseData
最后在您的其他组件上,您可以订阅。
public caseData;
ngOninit() {
this._caseService.GetCaseData()
// you can either subscribe and put it into local state, or you can pipe
// async into the template directly.
this._caseService.caseData$.subscribe( res => {
this.caseData = res;
})
}
UPDADE:详细说明异步管道。
异步管很棒!它是一个方便的助手,允许我们订阅observable而不用担心取消订阅。在我的代码中减少了很多锅炉板。要在示例中使用this._caseService.caseData$.subscribe( res => {
this.caseData = res;
})
管道:
而不是在组件上执行此操作
async
你可以在你的html
中拥有这个 this._caseService.caseData$.subscribe( res => {
this.caseData = res;
})
但请注意,每次使用 <div> {{ _caseService.caseData$ | async }} </div>
时,都会创建新的订阅。所以以下内容将创建重复订阅。
async
要远离这个,你可以使用
<div> {{ (_caseService.caseData$ | async)?.prop1 }} </div>
<div> {{ (_caseService.caseData$ | async)?.prop2 }} </div>
<div> {{ (_caseService.caseData$ | async)?.prop3 }} </div>
UDPATE 2:如果您已经使用了角度5,请使用httpclient!它会自动将您的REST resposne格式化为JSON。不再需要映射它。
<div *ngIf="_caseService.caseData$ | async as caseData">
<div> {{caseData.prop1}} <div>
<div> {{caseData.prop2}} <div>
<div> {{caseData.prop3}} <div>
</div>
我在服务中使用this._http.get(url, { headers: headers }).toPromise().then(res => {
caseDataStore.next(res);
});
,因为这是一次性通话,并且不想在之后取消订阅。或者,我见过其他人使用toPromise
。
更新3:如果您只想对从组件中获取的属性进行选择,则可以从您的可观察对象.first()
或map
。
假设您已在联系人组件中使用异步管道。
pluck
现在像往常一样订阅。如果你想进一步迈出这一步!您可以在应用中编写地图管道。
public contactCaseData$ = this._caseService.caseData$.map( data => {
return {data.prop1, data.prop2}
}
演示如何运作:https://stackblitz.com/edit/angular-ftxyns?file=app%2Fmap.pipe.ts
答案 1 :(得分:0)
您可以在组件中使用getter
//You can use in your .html
//{{caseData}}
get caseData()
{
return this._caseService.caseData;
}
另一个想法是订阅您的服务的Observable。 注意:它更好地使用HttpClient而不是#34; old&#34; HTTP