docs: edit getting started start-forms.md (#39681)

PR Close #39681
This commit is contained in:
Kapunahele Wong 2020-11-13 16:09:26 -05:00 committed by atscott
parent 087784aba1
commit 184d0e568f
9 changed files with 59 additions and 95 deletions

View File

@ -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() {
}
} }

View File

@ -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(

View File

@ -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();
} }
} }

View File

@ -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>

View File

@ -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
checkoutForm; items = this.cartService.getItems();
// #enddocregion checkout-form checkoutForm = this.formBuilder.group({
// #docregion inject-form-builder
constructor(
private cartService: CartService,
private formBuilder: FormBuilder,
) {
// #enddocregion inject-form-builder
this.checkoutForm = this.formBuilder.group({
name: '', name: '',
address: '' address: ''
}); });
// #enddocregion checkout-form
// #docregion inject-form-builder // #docregion inject-form-builder
} constructor(
private cartService: CartService,
ngOnInit() { private formBuilder: FormBuilder,
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
} }

View File

@ -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() {
}
} }

View File

@ -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
} }

View File

@ -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.

View File

@ -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. 1. Import the `FormBuilder` service from the `@angular/forms` package.
This service provides convenient methods for generating controls.
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="imports"> <code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts" region="imports">
</code-example> </code-example>
The `ReactiveFormsModule` provides the `FormBuilder` service, which `AppModule` (in `app.module.ts`) already imports. 1. Inject the `FormBuilder` service in the `CartComponent` `constructor()`.
This service is part of the `ReactiveFormsModule` module, which you've already imported.
1. Inject the `FormBuilder` service.
<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="inject-form-builder">
</code-example> </code-example>
1. Still in the `CartComponent` class, define the `checkoutForm` property to store the form model. 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="checkout-form">
</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, `{}`,
of the constructor.
<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 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. 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.
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: 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 header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.ts">
</code-example> </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.