[英]Observables in Angular and subscribe
我是 observable 的新手,我很難理解它是如何工作的!
我有一些代碼正在獲取數據的 JSON 文件,但我沒有在我的 ngOninit 上獲取它,我假設這是因為代碼是異步的。 我想設置一個 observable 以在數據進入后訂閱數據,但我對 observable 完全陌生。
這是代碼;
fetch('./assets/data/vendor.json').then(res => res.json())
.then(data => {
this.vendorData = data.vendors;
this.vendorService.setVendors(this.vendorData);
});
}
ngOnInit() {
this.filteredVendor = this.vendorService.getVendors();
this.isfiltered = true;
console.log(this.filteredVendor)
}
關於我如何實現這一點的任何想法以及您可以指出我學習 Observables 的任何好的教程或課程?
謝謝你的幫助。
在您的fetch
方法之后,您似乎使用.then
暗示您有一個承諾而不是一個可觀察的。 我建議您使用服務中 Rxjs 的from
方法將您的承諾轉換為可觀察的。 或者,您可以從中創建一個主題。
假設this.vendorService.getVendors()
返回一個 observable,您將必須像 @AliF50 在他的回答中建議的那樣訂閱它:
//Inside your get method in your service:
public getVendors(): Vendor[] {
return from(fetch('./assets/data/vendor.json')).pipe(map(
result => result.json()
));
}
現在,您將從對getVendors()
調用中獲得一個 observable。
// it is good practice to use a dollar sign at the end of a variable when its value is an observable
public ngOnInit() {
const vendors$ = this.vendorService.getVendors();
vendors$.subscribe((vendors: Vendor[]) => {
// The argument defined assuming the vendors observable resolves in an array of Vendor
// this.filteredVendor will be set when the observable emits the result
this.filteredVendor = vendors;
})
}
因為您是 Angular 中的 observables 的新手,所以我會建議一個可以對您的應用程序進行很好改進的解決方案:
如果您使用 observables 和 Angular,您還可以查看路由器的解析功能。 在此處的文檔中閱讀更多內容。
為您的供應商創建一個VendorResolver
:
@Injectable({ providedIn: 'root' })
export class VendorResolver implements Resolve<Vendor> {
constructor(private vendorService: VendorService) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<Vendor[]> {
return this.vendorService.getVendors();
}
}
在您的VendorService
:
public getVendors(): Observable<Vendor[]> {
// TODO: get fetch method available in the service, not sure where it comes from
// create a fetch$ observable using RxJs from (needs to be imported)
// from will convert your promise to an observable
const fetch$ = from(fetch('./assets/data/vendor.json'));
// pipe and map will map the observable result, return desired vendors from the map
return fetch$.pipe(map(result => {
const data = result.json();
return data.vendors;
}));
}
現在你可以在你的路線中做:
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'vendors',
component: VendorComponent,
resolve: {
vendors: VendorResolver
}
}
])
],
exports: [RouterModule]
})
export class AppRoutingModule {}
當路由到“供應商”路由時,路由器將使用VendorsResolver
自動解析您的供應商。 請注意,如果它不解決路由將不會完成。
在VendorComponent
您可以直接從路由快照數據訪問供應商:
class VendorsComponent {
constructor(private route: ActivatedRoute) {
}
public ngOnInit() {
this.filteredVendor = this.route.snapshot.data.vendors;
}
}
這使得組件中的代碼非常少; 除了ActivatedRoute
,無需注入任何其他內容來解決您的供應商問題。
注意:上面的代碼寫在這里並簡化了一點(例如組件類遠未完成),我跳過了導入語句。 我試圖盡可能准確和完整,但如果您有疑問或遇到問題,請發表評論,然后我可以在必要時添加一些詳細信息。
嘗試:
ngOnInit() {
this.vendorService.getVendors().subscribe(
venders => this.filteredVendor = venders;
this.isFiltered = true;
console.log(this.filteredVendor);
);
}
至於學習,我就一直在練習,看看怎么做。 這些教程可能已經過時,但它們對我有好處( https://egghead.io/courses/introduction-to-reactive-programming?fbclid=IwAR1I2--NX82Lg1iCvzLIx4vPtEw_PIbWid7eqboBT9RWI_h0G2zfE3i6hDA但可以學習新語法,但可以學習新語法)語法,沒那么難。
將 observable 視為可以用運算符修改的數據流。 要正確學習它,您將不得不親自動手並不斷嘗試解決與之相關的問題。 當您遇到困難或查看其他人的解決方案時,請繼續在 Stackoverflow 上發帖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.