[英]Angular - get synchronously from Promise
我想打印產品的歷史記錄。 我在ActivatedRoute.params中有一個產品ID。 在ngOnInit方法中,我必須獲取產品的所有歷史記錄並分配給變量。 然后,我想將產品映射到productHistory,因為我想要具有歷史記錄的最新版本。 但是問題在於獲取歷史記錄。 獲取歷史記錄的方法返回Promise,當我使用此屬性且未定義時,我無法獲得productHistory的長度。 從服務加載后如何獲得此屬性?
我想在執行getHistory()之后執行方法。
我的代碼:
ProductService.ts:
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
// rest imports
@Injectable()
export class ProductService {
// URL to web api
private projectsUrl = 'http://localhost:8080/products';
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http: Http) {}
getHistory(id: number): Promise<ProductHistory[]> {
const url = `${this.projectsUrl}/projectId/${id}`;
return this.http.get(url)
.toPromise()
.then(response => response.json() as ProductHistory[])
.catch(this.handleError);
}
handleError() {
//...
// implementation is irrelevant
}
}
ProductHistoryComponent.ts:
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import { ProductService } from './product.service';
import { ProductHistory } from './product-history';
import { Product } from './model/product';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'product-history',
templateUrl: './product-history.component.html',
styleUrls: [ './product-history.component.css' ]
})
export class ProductHistoryComponent implements OnInit {
auditProducts: ProductHistory[] = new Array<ProductHistory[]>();
selectedProduct: ProductHistory;
constructor(
private route: ActivatedRoute,
private location: Location,
private productService: ProductService
) {}
ngOnInit(): void {
let id: number = this.route.snapshot.params['id'];
this.productService.getHistory(id)
.then(history => this.historyProducts = history);
this.productService.getProduct(id)
.then(product => {
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
});
}
onSelect(ProductHistory: ProductHistory): void {
this.selectedProduct = ProductHistory;
this.compare(this.selectedProduct);
}
goBack(): void {
this.location.back();
}
compare(history: ProductHistory): void {
let previous: ProductHistory;
if (history.changeNumber != null && history.changeNumber > 1) {
previous = this.historyProducts[history.changeNumber - 2];
if (typeof previous != 'undefined') {
this.setPreviousDiffsFalse(previous);
if (previous.name !== history.name) {
history.nameDiff = true;
}
if (previous.price !== history.price) {
history.priceDiff = true;
}
}
}
}
createLastVersion(product: Product): ProductHistory {
let lastVersionProduct: ProductHistory = new ProductHistory();
lastVersionProduct.id = this.historyProducts.length + 1;
lastVersionProduct.name = product.name;
lastVersionProduct.price = product.price;
lastVersionProduct.changeNumber = this.historyProducts[this.historyProducts.length - 1].changeNumber + 1;
return lastVersionProduct;
}
setPreviousDiffsFalse(previous: ProductHistory): void {
previous.nameDiff = false;
previous.priceDiff = false;
}
}
我建議使用observables代替promise ...但是要回答您的問題,您只需要在收到第一個請求后執行第二個請求即可。 像這樣:
ngOnInit(): void {
let id: number = this.route.snapshot.params['id'];
this.productService.getHistory(id)
.then(history => {
this.historyProducts = history);
this.productService.getProduct(id)
.then(product => {
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
});
}
}
我剛搬到內 ,則第一個請求的第二請求。 注意:我沒有語法檢查此。
您不能同步運行它,您必須等待每個promise返回一個結果,然后才能對該結果執行某些操作。 通常的方法是在使用promise時將代碼嵌套在then
塊中。 另外,您也可以將async/await
與最新版本的Typescript一起使用,並且只需要更改component
代碼,因為您已經從服務中返回Promise
類型。 盡管發出的javascript代碼仍將使用函數/回調嵌套,這使代碼更易於閱讀(IMO)( 除非我相信您以es7為目標,否則也許有人會對此進行糾正或確認 )。
// note the use of async and await which gives the appearance of synchronous execution
async ngOnInit() {
let id: number = this.route.snapshot.params['id'];
const history = await this.productService.getHistory(id);
this.historyProducts = history;
const product = await this.productService.getProduct(id);
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.