parent
087784aba1
commit
184d0e568f
|
@ -1,15 +1,12 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-cart',
|
selector: 'app-cart',
|
||||||
templateUrl: './cart.component.html',
|
templateUrl: './cart.component.html',
|
||||||
styleUrls: ['./cart.component.css']
|
styleUrls: ['./cart.component.css']
|
||||||
})
|
})
|
||||||
export class CartComponent implements OnInit {
|
export class CartComponent {
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { CartService } from '../cart.service';
|
||||||
// #docregion inject-cart, items, submit
|
// #docregion inject-cart, items, submit
|
||||||
export class CartComponent {
|
export class CartComponent {
|
||||||
// #enddocregion inject-cart
|
// #enddocregion inject-cart
|
||||||
items;
|
items = this.cartService.getItems();
|
||||||
// #docregion inject-cart
|
// #docregion inject-cart
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class CartComponent implements OnInit {
|
||||||
private cartService: CartService
|
private cartService: CartService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit(): void {
|
||||||
this.items = this.cartService.getItems();
|
this.items = this.cartService.getItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- #docregion checkout-form-1 -->
|
<!-- #docregion checkout-form-1 -->
|
||||||
<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit(checkoutForm.value)">
|
<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
|
||||||
<!-- #enddocregion checkout-form-1 -->
|
<!-- #enddocregion checkout-form-1 -->
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion imports
|
// #docregion imports
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { FormBuilder } from '@angular/forms';
|
import { FormBuilder } from '@angular/forms';
|
||||||
|
|
||||||
import { CartService } from '../cart.service';
|
import { CartService } from '../cart.service';
|
||||||
|
@ -12,37 +12,27 @@ import { CartService } from '../cart.service';
|
||||||
styleUrls: ['./cart.component.css']
|
styleUrls: ['./cart.component.css']
|
||||||
})
|
})
|
||||||
// #docregion props-services, submit, inject-form-builder, checkout-form, checkout-form-group
|
// #docregion props-services, submit, inject-form-builder, checkout-form, checkout-form-group
|
||||||
export class CartComponent implements OnInit {
|
export class CartComponent {
|
||||||
items;
|
// #enddocregion inject-form-builder
|
||||||
// #enddocregion inject-form-builder
|
items = this.cartService.getItems();
|
||||||
checkoutForm;
|
checkoutForm = this.formBuilder.group({
|
||||||
|
name: '',
|
||||||
|
address: ''
|
||||||
|
});
|
||||||
// #enddocregion checkout-form
|
// #enddocregion checkout-form
|
||||||
// #docregion inject-form-builder
|
// #docregion inject-form-builder
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private cartService: CartService,
|
private cartService: CartService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
) {
|
) {}
|
||||||
// #enddocregion inject-form-builder
|
|
||||||
this.checkoutForm = this.formBuilder.group({
|
|
||||||
name: '',
|
|
||||||
address: ''
|
|
||||||
});
|
|
||||||
// #docregion inject-form-builder
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.items = this.cartService.getItems();
|
|
||||||
}
|
|
||||||
// #enddocregion inject-form-builder, checkout-form-group
|
// #enddocregion inject-form-builder, checkout-form-group
|
||||||
|
|
||||||
// #enddocregion props-services
|
// #enddocregion props-services
|
||||||
onSubmit(customerData) {
|
onSubmit(): void {
|
||||||
// Process checkout data here
|
// Process checkout data here
|
||||||
this.items = this.cartService.clearCart();
|
this.items = this.cartService.clearCart();
|
||||||
|
console.warn('Your order has been submitted', this.checkoutForm.value);
|
||||||
this.checkoutForm.reset();
|
this.checkoutForm.reset();
|
||||||
|
|
||||||
console.warn('Your order has been submitted', customerData);
|
|
||||||
}
|
}
|
||||||
// #docregion props-services, inject-form-builder, checkout-form, checkout-form-group
|
// #docregion props-services, inject-form-builder, checkout-form, checkout-form-group
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-shipping',
|
selector: 'app-shipping',
|
||||||
templateUrl: './shipping.component.html',
|
templateUrl: './shipping.component.html',
|
||||||
styleUrls: ['./shipping.component.css']
|
styleUrls: ['./shipping.component.css']
|
||||||
})
|
})
|
||||||
export class ShippingComponent implements OnInit {
|
export class ShippingComponent {
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion imports
|
// #docregion imports
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { CartService } from '../cart.service';
|
import { CartService } from '../cart.service';
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
@ -11,20 +11,17 @@ import { CartService } from '../cart.service';
|
||||||
styleUrls: ['./shipping.component.css']
|
styleUrls: ['./shipping.component.css']
|
||||||
})
|
})
|
||||||
// #docregion props, ctor
|
// #docregion props, ctor
|
||||||
export class ShippingComponent implements OnInit {
|
export class ShippingComponent {
|
||||||
shippingCosts;
|
shippingCosts = this.cartService.getShippingPrices();
|
||||||
// #enddocregion props
|
// #enddocregion props
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #docregion inject-cart-service
|
// #docregion inject-cart-service
|
||||||
constructor(
|
constructor(private cartService: CartService) {
|
||||||
private cartService: CartService
|
|
||||||
) {
|
|
||||||
}
|
}
|
||||||
// #enddocregion inject-cart-service
|
// #enddocregion inject-cart-service
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.shippingCosts = this.cartService.getShippingPrices();
|
|
||||||
}
|
|
||||||
|
|
||||||
// #docregion props
|
// #docregion props
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ For customers to see their cart, you can create the cart view in two steps:
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.1.ts"></code-example>
|
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.1.ts"></code-example>
|
||||||
|
|
||||||
|
StackBlitz also generates an `ngOnInit()` by default in components. You can ignore the `CartComponent` `ngOnInit()` for this tutorial.
|
||||||
|
|
||||||
1. Open `app.module.ts` and add a route for the component `CartComponent`, with a `path` of `cart`.
|
1. Open `app.module.ts` and add a route for the component `CartComponent`, with a `path` of `cart`.
|
||||||
|
|
||||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="cart-route">
|
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="cart-route">
|
||||||
|
@ -144,13 +146,8 @@ This section shows you how to use the cart service to display the products in th
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.2.ts" header="src/app/cart/cart.component.ts" region="items">
|
<code-example path="getting-started/src/app/cart/cart.component.2.ts" header="src/app/cart/cart.component.ts" region="items">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
1. Set the items using the `CartService` `getItems()` method.
|
This code sets the items using the `CartService` `getItems()` method.
|
||||||
You defined this method [when you created `cart.service.ts`](#generate-cart-service).
|
You defined this method [when you created `cart.service.ts`](#generate-cart-service).
|
||||||
By using the `getItems()` method in Angular's `ngOnInit()`, Angular uses `getItems()` upon initialization of `CartComponent`.
|
|
||||||
The resulting `CartComponent` class is as follows.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.3.ts" header="src/app/cart/cart.component.ts" region="props-services">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Update the cart template with a header, and use a `<div>` with an `*ngFor` to display each of the cart items with its name and price.
|
1. Update the cart template with a header, and use a `<div>` with an `*ngFor` to display each of the cart items with its name and price.
|
||||||
The resulting `CartComponent` template is as follows.
|
The resulting `CartComponent` template is as follows.
|
||||||
|
@ -251,17 +248,13 @@ This section guides you through modifying the `ShippingComponent` to retrieve sh
|
||||||
|
|
||||||
<code-example header="src/app/shipping/shipping.component.ts" path="getting-started/src/app/shipping/shipping.component.ts" region="imports"></code-example>
|
<code-example header="src/app/shipping/shipping.component.ts" path="getting-started/src/app/shipping/shipping.component.ts" region="imports"></code-example>
|
||||||
|
|
||||||
1. Define a `shippingCosts` property.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="props"></code-example>
|
|
||||||
|
|
||||||
1. Inject the cart service in the `ShippingComponent` `constructor()`.
|
1. Inject the cart service in the `ShippingComponent` `constructor()`.
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="inject-cart-service"></code-example>
|
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="inject-cart-service"></code-example>
|
||||||
|
|
||||||
1. Set the `shippingCosts` property using the `getShippingPrices()` method from the `CartService`.
|
1. Define a `shippingCosts` property that sets the `shippingCosts` property using the `getShippingPrices()` method from the `CartService`.
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="ctor"></code-example>
|
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="props"></code-example>
|
||||||
|
|
||||||
1. Update the `ShippingComponent` template to display the shipping types and prices using the `async` pipe.
|
1. Update the `ShippingComponent` template to display the shipping types and prices using the `async` pipe.
|
||||||
|
|
||||||
|
|
|
@ -1,61 +1,48 @@
|
||||||
# Using forms for user input
|
# Using forms for user input
|
||||||
|
|
||||||
At the end of [Managing Data](start/start-data "Try it: Managing Data"), the online store application has a product catalog and a shopping cart.
|
This guide builds on the [Managing Data](start/start-data "Try it: Managing Data") step of the Getting Started tutorial, [Get started with a basic Angular app](start "Get started with a basic Angular app").
|
||||||
|
|
||||||
This section walks you through adding a form-based checkout feature to collect user information as part of checkout.
|
This section walks you through adding a form-based checkout feature to collect user information as part of checkout.
|
||||||
|
|
||||||
## Forms in Angular
|
|
||||||
|
|
||||||
Forms in Angular build upon the standard HTML forms to help you create custom form controls and easy validation experiences. There are two parts to an Angular Reactive form: the objects that live in the component to store and manage the form, and the visualization of the form that lives in the template.
|
|
||||||
|
|
||||||
## Define the checkout form model
|
## Define the checkout form model
|
||||||
|
|
||||||
First, set up the checkout form model. Defined in the component class, the form model is the source of truth for the status of the form.
|
This step shows you how to set up the checkout form model in the component class.
|
||||||
|
The form model determines the status of the form.
|
||||||
|
|
||||||
1. Open `cart.component.ts`.
|
1. Open `cart.component.ts`.
|
||||||
|
|
||||||
1. Angular's `FormBuilder` service provides convenient methods for generating controls. As with the other services you've used, you need to import and inject the service before you can use it:
|
1. Import the `FormBuilder` service from the `@angular/forms` package.
|
||||||
|
This service provides convenient methods for generating controls.
|
||||||
|
|
||||||
1. Import the `FormBuilder` service from the `@angular/forms` package.
|
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="imports">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="imports">
|
1. Inject the `FormBuilder` service in the `CartComponent` `constructor()`.
|
||||||
</code-example>
|
This service is part of the `ReactiveFormsModule` module, which you've already imported.
|
||||||
|
|
||||||
The `ReactiveFormsModule` provides the `FormBuilder` service, which `AppModule` (in `app.module.ts`) already imports.
|
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="inject-form-builder">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
1. Inject the `FormBuilder` service.
|
1. To gather the user's name and address, use the `FormBuilder` `group()` method to set the `checkoutForm` property to a form model containing `name` and `address` fields.
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="inject-form-builder">
|
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="checkout-form-group"></code-example>
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Still in the `CartComponent` class, define the `checkoutForm` property to store the form model.
|
1. Define an `onSubmit()` method to process the form.
|
||||||
|
This method allows users to submit their name and address.
|
||||||
|
In addition, this method uses the `clearCart()` method of the `CartService` to reset the form and clear the cart.
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="checkout-form">
|
The entire cart component class is as follows:
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. To gather the user's name and address, set the `checkoutForm` property with a form model containing `name` and `address` fields, using the `FormBuilder` `group()` method. Add this between the curly braces, `{}`,
|
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts">
|
||||||
of the constructor.
|
</code-example>
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="checkout-form-group"></code-example>
|
|
||||||
|
|
||||||
1. For the checkout process, users need to submit their name and address. When they submit their order, the form should reset and the cart should clear.
|
|
||||||
|
|
||||||
1. In `cart.component.ts`, define an `onSubmit()` method to process the form. Use the `CartService` `clearCart()` method to empty the cart items and reset the form after its submission. In a real-world app, this method would also submit the data to an external server. The entire cart component class is as follows:
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
Now that you've defined the form model in the component class, you need a checkout form to reflect the model in the view.
|
|
||||||
|
|
||||||
## Create the checkout form
|
## Create the checkout form
|
||||||
|
|
||||||
Use the following steps to add a checkout form at the bottom of the "Cart" view.
|
Use the following steps to add a checkout form at the bottom of the Cart view.
|
||||||
|
|
||||||
1. Open `cart.component.html`.
|
1. At the bottom of `cart.component.html`, add an HTML `<form>` element and a **Purchase** button.
|
||||||
|
|
||||||
1. At the bottom of the template, add an HTML form to capture user information.
|
1. Use a `formGroup` property binding to bind `checkoutForm` to the HTML `<form>`.
|
||||||
|
|
||||||
1. Use a `formGroup` property binding to bind the `checkoutForm` to the `form` tag in the template. Also include a "Purchase" button to submit the form.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.html" path="getting-started/src/app/cart/cart.component.3.html" region="checkout-form">
|
<code-example header="src/app/cart/cart.component.html" path="getting-started/src/app/cart/cart.component.3.html" region="checkout-form">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
@ -65,21 +52,24 @@ Use the following steps to add a checkout form at the bottom of the "Cart" view.
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.html" header="src/app/cart/cart.component.html (cart component template detail)" region="checkout-form-1">
|
<code-example path="getting-started/src/app/cart/cart.component.html" header="src/app/cart/cart.component.html (cart component template detail)" region="checkout-form-1">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
1. Add input fields for `name` and `address`. Use the `formControlName` attribute binding to bind the `checkoutForm` form controls for `name` and `address` to their input fields. The final complete component is as follows:
|
1. Add `<input>` fields for `name` and `address`, each with a `formControlName` attribute that binds to the `checkoutForm` form controls for `name` and `address` to their `<input>` fields.
|
||||||
|
The complete component is as follows:
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.html" header="src/app/cart/cart.component.html" region="checkout-form-2">
|
<code-example path="getting-started/src/app/cart/cart.component.html" header="src/app/cart/cart.component.html" region="checkout-form-2">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
After putting a few items in the cart, users can now review their items, enter their name and address, and submit their purchase:
|
After putting a few items in the cart, users can review their items, enter their name and address, and submit their purchase.
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src='generated/images/guide/start/cart-with-items-and-form.png' alt="Cart view with checkout form">
|
<img src='generated/images/guide/start/cart-with-items-and-form.png' alt="Cart view with checkout form">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
To confirm submission, open the console where you should see an object containing the name and address you submitted.
|
To confirm submission, open the console to see an object containing the name and address you submitted.
|
||||||
|
|
||||||
## Next steps
|
<hr />
|
||||||
|
|
||||||
Congratulations! You have a complete online store application with a product catalog, a shopping cart, and a checkout function.
|
## What's next
|
||||||
|
|
||||||
|
You have a complete online store application with a product catalog, a shopping cart, and a checkout function.
|
||||||
|
|
||||||
[Continue to the "Deployment" section](start/start-deployment "Try it: Deployment") to move to local development, or deploy your app to Firebase or your own server.
|
[Continue to the "Deployment" section](start/start-deployment "Try it: Deployment") to move to local development, or deploy your app to Firebase or your own server.
|
||||||
|
|
Loading…
Reference in New Issue