[英]Multiple child components in parent component have the same instance angular2
[英]Angular2 parent child components
我正在使用Angular2应用程序,但无法弄清楚这个父/子部分。
我要实现的目标:一个“生产者”具有多个“产品”。 最后,我想检索每个生产者的产品列表。
问题是,我不知道如何将“产品”添加到“生产者”的列表中。
使用下面的代码,我对“产品”和“生产者”都进行了粗体操作,但是我不知道如何将“产品”添加到“生产者”中。
我的后端是Spring Boot + MongoDB后端。
我有我的producers.component,它调用模板来添加产品:
producers.component.html ,它调用addProduct()
<div *ngIf="selectedProducer">
<h2>{{selectedProducer.name | uppercase}} is my producer</h2>
<button (click)="gotoDetail()">View details</button>
<div>
<button (click)="addProduct()">Add product</button>
</div>
producers.component.ts addProduct()
addProduct(): void{
this.router.navigate(['/producers', this.selectedProducer.id,'addProduct']);
}
将app-routing.module.ts路由到ProductAddComponent
{ path: 'producers/:id/addProduct', component: ProductAddComponent }
product-add.component.html表单以添加产品
<h2>Add product</h2>
<div>
<form [formGroup]="productForm" (ngSubmit)="add(productForm)">
<span><h3>Add Product:</h3></span>
<label>Product id:</label><input formControlName="id"><br>
<label>Product ean:</label><input formControlName="ean"><br>
<label>Product name:</label><input formControlName="name"><br>
<span><h5>Nutrition per 100 grams:</h5></span>
<label>Energy (kcal)</label>
<input formControlName="kcal"><br>
<label>Saturated fat:</label>
<input formControlName="satFat"><br>
<label>Unsaturated fat:</label>
<input formControlName="unsatFat"><br>
<label>Carbohydrates:</label>
<input formControlName="carbs"><br>
<label>Protein:</label>
<input formControlName="protein"><br>
<label>Sugar:</label>
<input formControlName="sugar"><br>
<label>Salt:</label>
<input formControlName="salt"><br>
<button type="submit" class="btn btn-success">Submit</button>
</form>
product-add.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';
import { Nutrition } from '../model/nutrition';
import { Product } from '../model/product';
import { ProductService } from '../services/product.service';
import { Observable } from "rxjs/Observable";
import { Form, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'my-product-add',
templateUrl: '../templates/product-add.component.html',
styleUrls: ['../css/product-add.component.css'],
providers: [ProductService]
})
export class ProductAddComponent implements OnInit {
jsonResponse: string;
errorMessage: string;
products: Product[];
selectedProduct: Product;
lastRequestResult : boolean;
nameToAddInput: string;
@Input('producer') producerName: string;
productWithSpecifiedNameAlreadyExists: boolean = false;
public productForm: FormGroup;
constructor(
private router: Router,
private productService: ProductService,
private _fb: FormBuilder
) { }
ngOnInit(): void{
this.productForm = new FormGroup({
producer: new FormControl('', Validators.required),
id: new FormControl('', Validators.required),
name: new FormControl('', Validators.required),
ean: new FormControl('', Validators.required),
kcal: new FormControl('', Validators.required),
satFat: new FormControl('', Validators.required),
unsatFat: new FormControl('', Validators.required),
carbs: new FormControl('', Validators.required),
protein: new FormControl('', Validators.required),
sugar: new FormControl('', Validators.required),
salt: new FormControl('', Validators.required)
})
}
getProducts() {
this.productService.getProducts()
.subscribe(
(data) => {
this.jsonResponse = JSON.stringify(data);
this.products = data;
console.log(data);
})
}
add(product: Product): void {
var product : Product = new Product();
product.id = this.productForm.get('id').value.trim();
product.name = this.productForm.get('name').value.trim();
product.ean = this.productForm.get('ean').value.trim();
product.nutrition = {
kcal: this.productForm.get('kcal').value.trim(),
satFat: this.productForm.get('satFat').value.trim(),
unsatFat: this.productForm.get('unsatFat').value.trim(),
carbs: this.productForm.get('carbs').value.trim(),
protein: this.productForm.get('protein').value.trim(),
sugar: this.productForm.get('sugar').value.trim(),
salt: this.productForm.get('salt').value.trim()
};
this.productService.create(product)
.subscribe(
data => {
this.lastRequestResult = (data == "true");
this.productWithSpecifiedNameAlreadyExists = !this.lastRequestResult;
},
err => this.logError(err),
() => {
this.getProducts();
console.log("add request result: " + this.lastRequestResult);
console.log(product);
}
)
}
private logError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
产品服务
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import { Product } from '../model/product';
@Injectable()
export class ProductService {
private productsUrl = 'http://localhost:8181/api/products'; // url to web api
private producersUrl = 'http://localhost:8181/api/producers'; // url to web api
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http: Http) { }
getProducts(): Observable<Product[]>{
return this.http.get(this.productsUrl)
.map((res:Response) => res.json());
}
private getHeaders(){
let headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
getProduct(id: string): Observable<Product> {
const url = `${this.productsUrl}/${id}`;
return this.http.get(url)
.map((res:Response) => res.json());
}
update(product: Product): Promise<Product> {
const url = `${this.productsUrl}`;
return this.http
.put(url, JSON.stringify(product), {headers: this.headers})
.toPromise()
.then(() => product)
.catch(this.handleError);
}
create(product: Product): Observable<any> {
const url = `${this.productsUrl}/${product.id}`;
return this.http.post(url, product, {headers: this.headers})
.map(res => res.text());
}
delete(id: string): Promise<void> {
const url = `${this.productsUrl}/${id}`;
return this.http.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
}
任何帮助是极大的赞赏!!
根据每个生产者的估计20种产品,我建议采用以下方式构建MongoDB:
制片人
{
_id: objectId('58e655aabc8fe900119ae7a7')
producerName: 'Test producer',
products: [
ObjectId('593b28e80000000000000000')
]
}
产品展示
{
_id: ObjectId('593b28e80000000000000000'),
productName: 'Test product'
}
然后,当您将产品插入产品系列时,将其推入生产者产品阵列。 然后,您可以在应用程序中为生产者选择所有产品。
我没有使用过Spring Boot-所以这可能不合适-这就是我没有Spring boot的方式。 (我认为Spring Boot会这样做)
我也不确定您的问题是Angular,Spring boot还是mongo :)
我会将产品与生产者关联-每个生产者是否都生产一种产品? 还是可以由许多供应商生产产品?
如果是1:1,那么我将在创建产品消息中包含生产者ID。 然后将其存储在数据库中。
如果是多对多关系,那么您将需要一个组件和服务来创建关系。
我也看不到要在哪里显示列表? 我想,您想在生产者详细信息页面中显示它。 在这种情况下,当该组件加载时,我会向生产者及其产品发出获取请求。
无论如何-希望其中有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.