javascript - 使用我自己的模型類型屬性為 Angular2/typescript 模擬數據
我在 Angular2 的世界裡是新手。為了學習 Angular,我跟隨了不同的教程,現在我試著建立一個商店來學習更多。但我一開始就遇到了困難。
我正在嘗試將這個模型導入到 Angular 中:
但我沒有成功。我得到不同的錯誤,比如。
TypeError: 無法讀取未定義的屬性 'description',以及錯誤 TS2322: 類型 '{ ... }' 無法賦值給類型 'Product[]'。類型 ...
這是我目前為止得到的:
產品類型屬性模型
export class ProductTypeAttribute {
id: number;
name: string;
content: string;
}
產品類型型號
import { ProductTypeAttribute } from './product-type-attribute.model';
export class ProductType {
id: number;
name: string;
description: string;
attributeTypes: ProductTypeAttribute[];
}
產品型號
import { ProductType} from './product-type.model';
export class Product {
id: number;
name: string;
description: string;
image: string;
price: number;
type: ProductType;
}
模擬產品
import { Product } from './product.model';
import { ProductType } from './product-type.model';
import { ProductTypeAttribute } from './product-type-attribute.model';
export const productTypeAttributes: ProductTypeAttribute[] = [
{
id: 1,
name: 'Kleur',
content: 'test'
},
{
id: 2,
name: 'test',
content: 'test'
},
{
id: 3,
name: 'test',
content: 'test'
},
{
id: 4,
name: 'test',
content: 'test'
}
];
export const productTypeAttributes2: ProductTypeAttribute[] = [
{
id: 5,
name: 'Kleur',
content: 'test'
},
{
id: 6,
name: 'test',
content: 'test'
},
{
id: 7,
name: 'test',
content: 'test'
},
{
id: 8,
name: 'test',
content: 'test'
}
];
export const productType: ProductType =
{
id: 1,
name: 'Type 1',
description: 'Description of type 1',
attributeTypes: productTypeAttributes
};
export const productType2: ProductType =
{
id: 2,
name: 'Type 2',
description: 'Description of type 2',
attributeTypes: productTypeAttributes2
};
export const products: Product[] = [
{
id: 1,
name: 'Product 1',
description: 'Description of product 1',
image: 'https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8',
price: 15.15,
type: productType
},
{
id: 2,
name: 'Product 2',
description: 'Description of product 2',
image: 'https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8',
price: 15.15,
type: productType
},
{
id: 3,
name: 'Product 3',
description: 'Description of product 3',
image: 'https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8',
price: 15.15,
type: productType2
}
];
產品服務
import { Injectable } from '@angular/core';
import { Product } from './../shared/product.model';
import { products } from './../shared/mock-products';
@Injectable()
export class ProductService {
getProducts(): Promise<Product[]> {
return Promise.resolve(products);
}
getProduct(id: number): Promise<Product> {
return this.getProducts().then(products => products.find(product => product.id === id));
}
}
產品組件
import { Component, OnInit } from '@angular/core';
import { Product } from './../shared/product.model';
import { ProductService } from './../product/product.service';
@Component({
selector: 'product',
template: require('./product.component.html'),
providers: [ProductService]
})
export class ProductComponent implements OnInit {
product: Product;
constructor(private productService: ProductService) { }
getProduct(): void {
this.productService.getProduct(1).then(product => this.product = product);
}
ngOnInit(): void {
this.getProduct();
}
}
產品 HTML
<div class="product">
<div class="header">
<h1>{{product?.name}}</h1>
<h4></h4>
</div>
<figure>
<img src="{{product?.image}}">
</figure>
<section>
<p>{{product?.description}}</p>
<details>
<summary>Product Features</summary>
<ul>
<li *ngFor="let productAttribute of product?.type?.attributeTypes">
{{productAttribute?.name}}
</li>
</ul>
</details>
<button>Buy Now</button>
</section>
我希望我已經清楚地說明了我的問題,也希望你們能在這裡幫助我。
更新
*更新** 好的,現在事情變得瘋狂了。當我這麼做的時候
export const products: ({ id: number;description: string;image: string;price: number;type: Object } |
{ id: number;name: string;description: string;image: string;price: number;type: Object })[] = [
{
id: 1,
description: "Description of product 1",
image: "https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8",
price: 15.15,
type: productType
},
{
id: 2,
name: "Product 2",
description: "Description of product 2",
image: "https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8",
price: 15.15,
type: productType
},
{
id: 3,
name: "Product 3",
description: "Description of product 3",
image: "https://www.google.nl/imgres?imgurl=https%3A%2F%2Fangular.io%2Fresources%2Fimages%2Flogos%2Fangular2%2Fangular.svg&imgrefurl=https%3A%2F%2Fangular.io%2F&docid=bJoyJcb-C12SHM&tbnid=G_BYSyR7DGpqqM%3A&vet=1&w=800&h=800&bih=1060&biw=1060&q=angular2&ved=0ahUKEwjdrq6it87RAhUEExoKHdXlAYIQMwgcKAAwAA&iact=mrc&uact=8",
price: 15.15,
type: productType2
}
它沒有報錯,但不顯示名稱。
答案#1
實際測試了你的程式碼,似乎只有非同步問題。試試使用安全操作符:?(也稱為 elvis 操作符)如下所示:
<h1>{{product?.name}}</h1>
另一個選擇是這樣使用 *ngIf:
<h1 *ngIf="product">{{product.name}}</h1>
在這裡可以了解更多關於 Elvis 運算子的資訊。這在 Angular (2) 應用程式中非常方便,因為我們經常需要處理非同步操作,通常視圖是在接收資料之前就已經呈現了。
如果你偏好 *ngIf,這也可以使用,應用程式不會拋出錯誤,因為你包裹在其中的程式碼只有在存在資料時才會被渲染,在這個例子中是你的 product 物件。
運作中的 Plunker
你可以將你的類別改為介面,因此:
export interface Product {
id: number;
name: string;
description: string;
image: string;
price: number;
type: ProductType;
}
或者為你的類別添加建構子:
export class Product {
constructor(
public id: number,
public name: string,
public description: string,
public image: string,
public price: number,
public type: ProductType
) { }
}

