docs(forms): Add documentation and live examples for NgForm, NgFormControl, NgFormModel, and NgModel.

Closes #4343
This commit is contained in:
Alex Rickabaugh 2015-09-23 13:28:50 -07:00
parent 4e5c663b02
commit 711ab6d573
4 changed files with 117 additions and 63 deletions

View File

@ -19,36 +19,64 @@ const formDirectiveBinding =
CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgForm)})); CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgForm)}));
/** /**
* Creates and binds a form object to a DOM element. * If `NgForm` is bound in a component, `<form>` elements in that component will be
* upgraded to use the Angular form system.
* *
* # Example * # Typical Use
* *
* ``` * Include `FORM_DIRECTIVES` in the `directives` section of a {@link View} annotation
* @Component({selector: "signup-comp"}) * to use `NgForm` and its associated controls.
*
* # Structure
*
* An Angular form is a collection of {@link Control}s in some hierarchy.
* `Control`s can be at the top level or can be organized in {@link ControlGroups}
* or {@link ControlArray}s. This hierarchy is reflected in the form's `value`, a
* JSON object that mirrors the form structure.
*
* # Submission
*
* The `ng-submit` event signals when the user triggers a form submission.
*
* ### Example ([live demo](http://plnkr.co/edit/ltdgYj4P0iY64AR71EpL?p=preview))
*
* ```typescript
* @Component({
* selector: 'my-app'
* })
* @View({ * @View({
* directives: [FORM_DIRECTIVES],
* template: ` * template: `
* <form #f="form" (submit)='onSignUp(f.value)'> * <div>
* <div ng-control-group='credentials' #credentials="form"> * <p>Submit the form to see the data object Angular builds</p>
* Login <input type='text' ng-control='login'> * <h2>NgForm demo</h2>
* Password <input type='password' ng-control='password'> * <form #f="form" (ng-submit)="onSubmit(f.value)">
* <h3>Control group: credentials</h3>
* <div ng-control-group="credentials">
* <p>Login: <input type="text" ng-control="login"></p>
* <p>Password: <input type="password" ng-control="password"></p>
* </div> * </div>
* <div *ng-if="!credentials.valid">Credentials are invalid</div> * <h3>Control group: person</h3>
* * <div ng-control-group="person">
* <div ng-control-group='personal'> * <p>First name: <input type="text" ng-control="firstName"></p>
* Name <input type='text' ng-control='name'> * <p>Last name: <input type="text" ng-control="lastName"></p>
* </div> * </div>
* <button type='submit'>Sign Up!</button> * <button type="submit">Submit Form</button>
* <p>Form data submitted:</p>
* </form> * </form>
* `}) * <pre>{{data}}</pre>
* class SignupComp { * </div>
* onSignUp(value): void { * `,
* // value === { * directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
* // personal: {name: 'some name'}, * })
* // credentials: {login: 'some login', password: 'some password'}} * export class App {
* } * constructor() {}
* }
* *
* data: string;
*
* onSubmit(data) {
* this.data = JSON.stringify(data, null, 2);
* }
* }
* ``` * ```
*/ */
@Directive({ @Directive({

View File

@ -12,29 +12,43 @@ const formControlBinding =
CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgFormControl)})); CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgFormControl)}));
/** /**
* Binds an existing control to a DOM element. * Binds an existing {@link Control} to a DOM element.
* *
* # Example * ### Example ([live demo](http://plnkr.co/edit/jcQlZ2tTh22BZZ2ucNAT?p=preview))
* *
* In this example, we bind the control to an input element. When the value of the input element * In this example, we bind the control to an input element. When the value of the input element
* changes, the value of the control will reflect that change. Likewise, if the value of the * changes, the value of the control will reflect that change. Likewise, if the value of the
* control changes, the input element reflects that change. * control changes, the input element reflects that change.
* *
* ``` * ```typescript
* @Component({selector: "login-comp"}) * @Component({
* @View({ * selector: 'my-app'
* directives: [FORM_DIRECTIVES],
* template: "<input type='text' [ng-form-control]='loginControl'>"
* }) * })
* class LoginComp { * @View({
* loginControl: Control = new Control('');; * template: `
* <div>
* <h2>NgFormControl Example</h2>
* <form>
* <p>Element with existing control: <input type="text"
* [ng-form-control]="loginControl"></p>
* <p>Value of existing control: {{loginControl.value}}</p>
* </form>
* </div>
* `,
* directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
* })
* export class App {
* loginControl: Control = new Control('');
* } * }
*
* ``` * ```
* *
* # ng-model
*
* We can also use `ng-model` to bind a domain model to the form. * We can also use `ng-model` to bind a domain model to the form.
* *
* ``` * ### Example ([live demo](http://plnkr.co/edit/yHMLuHO7DNgT8XvtjTDH?p=preview))
*
* ```typescript
* @Component({selector: "login-comp"}) * @Component({selector: "login-comp"})
* @View({ * @View({
* directives: [FORM_DIRECTIVES], * directives: [FORM_DIRECTIVES],

View File

@ -18,23 +18,30 @@ const formDirectiveBinding =
/** /**
* Binds an existing control group to a DOM element. * Binds an existing control group to a DOM element.
* *
* # Example * ### Example ([live demo](http://plnkr.co/edit/jqrVirudY8anJxTMUjTP?p=preview))
* *
* In this example, we bind the control group to the form element, and we bind the login and * In this example, we bind the control group to the form element, and we bind the login and
* password controls to the login and password elements. * password controls to the login and password elements.
* *
* ``` * ```typescript
* @Component({selector: "login-comp"}) * @Component({
* @View({ * selector: 'my-app'
* directives: [FORM_DIRECTIVES],
* template: `
* <form [ng-form-model]='loginForm'>
* Login <input type='text' ng-control='login'>
* Password <input type='password' ng-control='password'>
* <button (click)="onLogin()">Login</button>
* </form>`
* }) * })
* class LoginComp { * @View({
* template: `
* <div>
* <h2>NgFormModel Example</h2>
* <form [ng-form-model]="loginForm">
* <p>Login: <input type="text" ng-control="login"></p>
* <p>Password: <input type="password" ng-control="password"></p>
* </form>
* <p>Value:</p>
* <pre>{{value}}</pre>
* </div>
* `,
* directives: [FORM_DIRECTIVES]
* })
* export class App {
* loginForm: ControlGroup; * loginForm: ControlGroup;
* *
* constructor() { * constructor() {
@ -44,16 +51,15 @@ const formDirectiveBinding =
* }); * });
* } * }
* *
* onLogin(): void { * get value(): string {
* // this.loginForm.value * return JSON.stringify(this.loginForm.value, null, 2);
* } * }
* } * }
*
* ``` * ```
* *
* We can also use ng-model to bind a domain model to the form. * We can also use ng-model to bind a domain model to the form.
* *
* ``` * ```typescript
* @Component({selector: "login-comp"}) * @Component({selector: "login-comp"})
* @View({ * @View({
* directives: [FORM_DIRECTIVES], * directives: [FORM_DIRECTIVES],

View File

@ -13,10 +13,16 @@ import {setUpControl, isPropertyUpdated} from './shared';
const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgModel)})); const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgModel)}));
/** /**
* Binds a domain model to the form. * Binds a domain model to a form control.
* *
* # Example * # Usage
* ``` *
* `ng-model` binds an existing domain model to a form control. For a
* two-way binding, use `[(ng-model)]` to ensure the model updates in
* both directions.
*
* ### Example ([live demo](http://plnkr.co/edit/R3UX5qDaUqFO2VYR0UzH?p=preview))
* ```typescript
* @Component({selector: "search-comp"}) * @Component({selector: "search-comp"})
* @View({ * @View({
* directives: [FORM_DIRECTIVES], * directives: [FORM_DIRECTIVES],