如何将数据从一个窗体传递到另一个角度组件



我的购物车项目组件中有一个表单。它应该被用作结账页面。当用户用他们的信息填写表单并选择按钮时,我需要将他们发送到一个确认页面,该页面显示他们刚刚输入表单的所有数据。我在将数据从购物车项目组件传递到确认组件时遇到问题。我觉得我应该使用一项服务,但我是个新手,不确定如何做到这一点。

购物车项目HTML:

<form #userForm="ngForm"(ngSubmit)="onClickSubmit(userForm.value)" >
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName">First name</label>
<input type="text" ngModel name="firstName" #firstName="ngModel"class="form-control" id="firstName" placeholder="" value="" required>
<div class="alert alert-danger"*ngIf=" firstName.touched && !firstName.valid" >
First Name is required.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastName">Last name</label>
<input type="text" ngModel name="lastName" #lastName="ngModel"class="form-control" id="lastName" placeholder="" value="" required>
<div class="alert alert-danger"*ngIf=" lastName.touched && !lastName.valid" >
Last Name is required.
</div>
</div>
</div>


<div class="mb-3">
<label for="email">Email <span class="text-muted">(Optional)</span></label>
<input type="email" class="form-control" id="email" placeholder="you@example.com">
<div class="invalid-feedback">
Please enter a valid email address for shipping updates.
</div>
</div>

<div class="mb-3">
<label for="address">Address</label>
<input type="text" ngModel name="address" #address="ngModel"class="form-control" id="address" placeholder="" value="" required>
<div class="alert alert-danger"*ngIf="address.touched && !address.valid" >
Address is required.
</div>

</div>


<div class="row">
<div class="col-md-5 mb-3">
<label for="country">Country</label>
<select class="custom-select d-block w-100" id="country" required>
<option>United States</option>
</select>
<div class="invalid-feedback">
Please select a valid country.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="state">State</label>
<select class="custom-select d-block w-100" id="state" required>
<option value="">Choose...</option>
<option>California</option>
<option>Pennsylvania</option>
</select>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="zip">Zip</label>
<input type="text" class="form-control" ngModel name="zip" #zip="ngModel" id="zip" placeholder="" required>
<div class="alert alert-danger"*ngIf="zip.touched && !zip.valid">
Zip code required.
</div>
</div>
</div>




<h4 class="mb-3">Payment</h4>

<div class="d-block my-3">
<div class="custom-control custom-radio">
<input id="credit" name="paymentMethod" type="radio" class="custom-control-input" checked required>
<label class="custom-control-label" for="credit">Credit card</label>
</div>
<div class="custom-control custom-radio">
<input id="debit" name="paymentMethod" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="debit">Debit card</label>
</div>
<div class="custom-control custom-radio">
<input id="paypal" name="paymentMethod" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="paypal">PayPal</label>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="cc-name">Name on card</label>
<input type="text" class="form-control" ngModel name="name" #name="ngModel" id="cc-name" placeholder="" required>
<small class="text-muted">Full name as displayed on card</small>
<div class="alert alert-danger"*ngIf="name.touched && !name.valid">
Name on card is required
</div>
</div>
<div class="col-md-6 mb-3">
<label for="cc-number">Credit card number</label>
<input type="text" ngModel name="card" #card="ngModel" class="form-control" id="cc-number" placeholder="" required>
<div class="alert alert-danger"*ngIf="card.touched && !card.valid">
Credit card number is required
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<label for="cc-expiration">Expiration</label>
<input type="text" class="form-control" ngModel name="expiration" #expiration="ngModel" id="cc-expiration" placeholder="" required>
<div class="alert alert-danger"*ngIf="expiration.touched && !expiration.valid">
Expiration date required
</div>
</div>
<div class="col-md-3 mb-3">
<label for="cc-cvv">CVV</label>
<input type="text" class="form-control" ngModel name="cvv" #cvv="ngModel" id="cc-cvv" placeholder="" required>
<div class="alert alert-danger"*ngIf="cvv.touched && !cvv.valid">
Security code required
</div>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit" [disabled]="userForm.invalid">Purchase Product(s)</button>
</form>

cart-item.ts:

import { Component, OnInit,Input } from '@angular/core';
import { Product } from '../product';
import { CardComponent } from '../card/card.component'
import { Router } from '@angular/router'
@Component({
selector: 'app-cart-item',
templateUrl: './cart-item.component.html',
styleUrls: ['./cart-item.component.css']
})
export class CartItemComponent implements OnInit {
@Input() product!: Product;
namesOfDestinations:any=[];
descriptions:any=[]
prices:any=[];
totalPrice:number=0;
items:any=[];
confirmPurchase:any=[];
constructor(public router: Router) { }
ngOnInit(): void {

// console.log(this.cart)
// this.cartItems()
this.getNames()
this.getDescription()
this.getPrice()
this.getLocalStorageLength()
this.getTotalPrice()
}
onClickSubmit(data:any){
this.router.navigate(['/confirmation'])
this.confirmPurchase.push(data)
console.log(this.confirmPurchase)
}
}

确认页面html:

<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="center" style="background-color: #eeeeee;" bgcolor="#eeeeee">
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:600px;">
<tr>
<td align="center" valign="top" style="font-size:0; padding: 35px;" bgcolor="#F44336">

<div style="display:inline-block; max-width:50%; min-width:100px; vertical-align:top; width:100%;" class="mobile-hide">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
<tr>
<td align="right" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
<table cellspacing="0" cellpadding="0" border="0" align="right">

</table>
</td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td align="center" style="padding: 35px 35px 20px 35px; background-color: #ffffff;" bgcolor="#ffffff">
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:600px;">
<tr>
<td align="center" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding-top: 25px;"> <img src="https://img.icons8.com/carbon-copy/100/000000/checked-checkbox.png" width="125" height="120" style="display: block; border: 0px;" /><br>
<h2 style="font-size: 30px; font-weight: 800; line-height: 36px; color: #333333; margin: 0;"> Thank You For Your Order! </h2>
</td>
</tr>
<tr>

</tr>
<tr>
<td align="left" style="padding-top: 20px;">
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td width="75%" align="left" bgcolor="#eeeeee" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 800; line-height: 24px; padding: 10px;"> Order Confirmation # </td>
<td width="25%" align="left" bgcolor="#eeeeee" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 800; line-height: 24px; padding: 10px;"> 2345678 </td>
</tr>
<tr>
<td width="75%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 15px 10px 5px 10px;"> Name: </td>
<td width="25%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 15px 10px 5px 10px;">{{data.firstName}}<br>{{data.lastName}} </td>
</tr>
<tr>
<td width="75%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 5px 10px;"> Email </td>
<td width="25%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 5px 10px;"> {{data.email}} </td>
</tr>

</table>
</td>
</tr>
<tr>
<td align="left" style="padding-top: 20px;">
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>

</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center" height="100%" valign="top" width="100%" style="padding: 0 35px 35px 35px; background-color: #ffffff;" bgcolor="#ffffff">
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:660px;">
<tr>
<td align="center" valign="top" style="font-size:0;">
<div style="display:inline-block; max-width:50%; min-width:240px; vertical-align:top; width:100%;">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
<tr>
<td align="left" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px;">
<p style="font-weight: 800;">Delivery Address</p>
<p>{{data.address}}<br>{{data.country}}<br>{{data.state}}<br>{{data.zip}}</p>
</td>
</tr>
</table>
</div>
<div style="display:inline-block; max-width:50%; min-width:240px; vertical-align:top; width:100%;">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
<tr>
<td align="left" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px;">
<p style="font-weight: 800;">Credit Card Information</p>
<p>{{data.card}}<br>{{data.expiration}},{{data.cvv}}</p>

</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</td>
</tr>

</table>
</td>
</tr>
</table>

您可以尝试如下,

修改购物车项目组件中的onClickSubmit方法

onClickSubmit(data: any) {
this.confirmPurchase.push(data)
console.log(this.confirmPurchase)
this.sharedService.setCartItemData(this.confirmPurchase);
this.router.navigate(['/confirmation'])
}

使用BehaviorSubject变量创建服务类以便在两个组件之间传递数据。

@Injectable()
export class SharedService {
public cartItemData = new BehaviorSubject<any>([]);
constructor() { }

setCartItemData(data: any) {
this.cartItemData.next(data);
}
getCartItemData() {
return this.cartItemData.asObservable();
}
}

确认页面.组件.ts

ngOnInit() {
this.sharedService.getCartItemData().subscribe(data => {
console.log('form data ', data);
});
}

StackBlitz,带有供您参考的示例代码。

onClickSubmit(data:any){
this.router.navigate(['/confirmation'])
this.confirmPurchase.push(data)
console.log(this.confirmPurchase)
}

当前不应执行您的confirmPurchase.push(数据(行。您在导航到"/confirmation"路径后执行此操作。

如果您需要进行任何更改,您需要在导航到之前进行更改另一条路。

在发送组件中,您可以使用类似于构造函数中的服务

constructor(private dataService: DataService) { }
private newData = new BehaviorSubject<any>({
name: 'K',
mail: 'kathy@go.com',
});
setNewData(data: any) {
this.newData.next(data);
}
getNewDataInfo() {
return this.newData.asObservable();
}

在接收组件中,您可以使用服务的getNewDataInfo来接收传递的数据。

返回的数据将是可观察的,您可以订阅它来接收您需要的数据。

最新更新