私はAngular2/TypeScriptがかなり新しいので、バカな間違いをしているのなら、すみません。私がやろうとしているのは、Selectドロップダウンから、JSON配列を返すサービスを使用してデータを入力しています。
ここに私のコードがあります:
product-maintenance.component.ts
import { Component, OnInit} from '@angular/core';
import { ProductMaintenanceService } from '../../_services/product-maintenance.service';
import { ModuleConst } from '../../../data/const';
import { Product } from './product-types';
import { Products } from './products';
@Component({
selector: 'app-product-maintenance',
templateUrl: './product-maintenance.component.html',
styleUrls: ['./product-maintenance.component.css']
})
export class ProductMaintenanceComponent implements OnInit {
selectedProduct: Product = new Product(0, 'Insurance');
products: Product[];
productList: Products[];
constructor( private productService: ProductMaintenanceService ) {
}
ngOnInit() {
// Dropdown list
this.products = this.productService.getProductTypeList();
}
// Populate data using onSelect method
onSelect(typeid) {
this.productList = this.productService.getProducts()
.filter((item)=>item.ptypeid == typeid);
}
}
product-type.ts
(ドロップダウンリストの設定に使用):
export class Product {
constructor(
public ptypeid: number,
public name: string
) { }
}
products.ts
(サービスからデータを取り込むために使用):
export class Products {
constructor(
public id: number,
public ptypeid: number,
public name: string,
public currency: string,
public state: string,
public riskRating: number,
public clientSegment: string,
public aiStatus: string,
public premiumType: string,
public tenure: number
) { }
}
product-maintenance.service.ts
:
import { Injectable, Inject } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
import { APP_CONFIG, IAppConfig } from '../app.config';
import { Products } from './products';
import { Product } from './product-types';
@Injectable()
export class ProductMaintenanceService {
result: Array<Object>;
constructor(
@Inject(APP_CONFIG) private config: IAppConfig,
private http: Http
) { }
private productURL = 'data/productList.json';
// Get product list
getProducts() : Observable<any> {
// ...using get request
return this.http.get(this.productURL)
// ...and calling .json() on the response to return data
.map((response: Response) => {
console.log(response);
return response.json();
});
}
getProductTypeList() {
return [
new Product(1, 'Unit Trust'),
new Product(2, 'Insurance'),
new Product(3, 'Structured Deposit'),
new Product(4, 'Bonds'),
new Product(5, 'DCI'),
new Product(6, 'SP')
];
}
}
product-maintenance.component.html
:
<table>
<tr *ngFor="let item of productList">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.currency }}</td>
<td>{{ item.state }}</td>
<td>{{ item.riskRating }}</td>
<td>{{ item.clientSegment }}</td>
<td>{{ item.aiStatus }}</td>
<td>{{ item.premiumType }}</td>
<td>{{ item.tenure }}</td>
</tr>
</table>
productList.json
:
[
{
"ptypeid": 1,
"id": 1,
"name": "Unit Trust 1",
"currency": "SGD",
"state": "Active",
"riskRating": 1,
"clientSegment": "Retail/Premier",
"aiStatus": "No",
"premiumType": "Regular Premium",
"tenure": 5
},
{
"ptypeid": 2,
"id": 2,
"name": "Unit Trust 2",
"currency": "SGD",
"state": "Active",
"riskRating": 3,
"clientSegment": "Retail/Premier",
"aiStatus": "No",
"premiumType": "Single/Lumpsum Premium",
"tenure": 10
}
]
getProducts()
をgetProductTypeList()
として定義すると、ビューのデータが完全に読み込まれます(ドロップダウンから[ユニットの信頼]を選択すると、関連データが読み込まれます)。しかし、代わりにapi urlとして使用すると、以下のエラーが表示されます:
Type 'Observable<any>' is not assignable to type 'Products[]'. Property 'length' is missing in type 'Observable<any>'
このエラーを解決する方法がわかりません。誰でもこれで私を助けてください。前もって感謝します。
productList
はProduct[]
ではなくObservable<any>
である必要があります。したがって、productList
subscribeメソッドからgetProducts
値を割り当てます。ここで、Product
の配列を取得します
onSelect(typeid) {
this.productService.getProducts()
.filter((item)=>item.ptypeid == typeid)
.subscribe((products) => {
this.productList = products;
});
}
メソッドをgetProductsメソッドに変更します
getProducts() : Observable<any> {
// ...using get request
let response = this.http.get(this.productURL)
// ...and calling .json() on the response to return data
.map((response: Response) => response.json());
return response;
}
いくつかの問題があります。最初に、get-requestに相対URLを使用していることに気付きました。それはうまくいきません。正しいURLが必要です。つまり、APIがlocalhostにある場合でも、http://..
で始まるものは完全なURLを提供する必要があります。
次に、getリクエストは問題ありませんが、コンポーネントでの呼び出しは次のようになります。
this.productService.getProducts()
.subscribe(data => {
this.productList = data})
リクエストでマップを実行しているので、それもサブスクライブする必要があります。そうしないと、結果が得られません!
また、言及する価値があるのは、これは非同期操作であるため、データが到着する前にビューがレンダリングされた場合にアプリがエラーをスローしないように、テーブルにngIf
を含めることができます。この:
<table *ngIf="productList">
これで事態は一掃されるはずです!
または、サブスクライブしたくない場合は、以前と同じように実行できます。
this.products = this.productService.getProductTypeList();
ただし、ビューでasync
パイプを使用する必要があります。
<tr *ngFor="let item of productList | async">
この場合、async-pipeがサブスクリプションを行います:)