关于angular实现表单的一些问题
如何用angular实现表单的一些问题?核心步骤大概如下:
-
创建模型类
-
创建控制此表单的组件。
-
创建具有初始表单布局的模板。
-
使用
ngModel
双向数据绑定语法把数据属性绑定到每个表单输入控件。 -
往每个表单输入控件上添加
name
属性 (attribute)。 -
添加自定义 CSS 来提供视觉反馈。
-
显示和隐藏有效性验证的错误信息。
-
使用 ngSubmit 处理表单提交。
-
禁用此表单的提交按钮,直到表单变为有效。
-------------理论到此结束,我是最不华丽的分割线-----------------------------------
一:需要哪些文件?
一图胜千言,哈哈哈哈!!!
(PS:不要问我那些文件分别是干嘛的,因为我也说不清楚!)
二:你要的代码
app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: '<hero-form></hero-form>' }) export class AppComponent { }
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { HeroFormComponent } from './hero-form.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, HeroFormComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
hero-form.component.html
<div class="container"> <div [hidden]="submitted"> <h1>Hero Form</h1> <form (ngSubmit)="onSubmit()" #heroForm="ngForm"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #name="ngModel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> Name is required </div> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required [(ngModel)]="model.power" name="power" #power="ngModel"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> <div [hidden]="power.valid || power.pristine" class="alert alert-danger"> Power is required </div> </div> <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button> <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button> <i>with</i> reset <button type="button" class="btn btn-default" (click)="newHero()">New Hero</button> <i>without</i> reset <!-- NOT SHOWN IN DOCS --> <div> <hr> Name via form.controls = {{showFormControls(heroForm)}} </div> <!-- - --> </form> </div> <div [hidden]="!submitted"> <h2>You submitted the following:</h2> <div class="row"> <div class="col-xs-3">Name</div> <div class="col-xs-9 pull-left">{{ model.name }}</div> </div> <div class="row"> <div class="col-xs-3">Alter Ego</div> <div class="col-xs-9 pull-left">{{ model.alterEgo }}</div> </div> <div class="row"> <div class="col-xs-3">Power</div> <div class="col-xs-9 pull-left">{{ model.power }}</div> </div> <br> <button class="btn btn-primary" (click)="submitted=false">Edit</button> </div> </div> <!-- ==================================================== --> <div> <form> <!-- ... all of the form ... --> </form> </div> <!-- ==================================================== --> <hr> <style> .no-style .ng-valid { border-left: 1px solid #CCC } .no-style .ng-invalid { border-left: 1px solid #CCC } </style> <div class="no-style" style="margin-left: 4px"> <div class="container"> <h1>Hero Form</h1> <form> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> <!-- ==================================================== --> <hr> <div class="container"> <h1>Hero Form</h1> <form> {{diagnostic}} <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required [(ngModel)] ="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> <!-- EXTRA MATERIAL FOR DOCUMENTATION --> <hr> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> TODO: remove this: {{model.name}} <hr> <input type="text" class="form-control" id="name" required [ngModel]="model.name" name="name" (ngModelChange)="model.name = $event"> TODO: remove this: {{model.name}} <hr> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #spy> <br>TODO: remove this: {{spy.className}} </div>
hero-form.component.ts
import { Component } from '@angular/core'; import { Hero } from './hero'; @Component({ moduleId: module.id, selector: 'hero-form', templateUrl: './hero-form.component.html' }) export class HeroFormComponent { powers = ['Really Smart', 'Super Flexible', 'Super Hot', 'Weather Changer']; model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); submitted = false; onSubmit() { this.submitted = true; } // TODO: Remove this when we're done get diagnostic() { return JSON.stringify(this.model); } newHero() { this.model = new Hero(42, '', ''); } skyDog(): Hero { let myHero = new Hero(42, 'SkyDog', 'Fetch any object at any distance', 'Leslie Rollover'); console.log('My hero is called ' + myHero.name); // "My hero is called SkyDog" return myHero; } //////// NOT SHOWN IN DOCS //////// // Reveal in html: // Name via form.controls = {{showFormControls(heroForm)}} showFormControls(form: any) { return form && form.controls['name'] && form.controls['name'].value; // Dr. IQ } }
hero.ts
export class Hero { constructor( public id: number, public name: string, public power: string, public alterEgo?: string ) { } }
forms.css
.ng-valid[required], .ng-valid.required { border-left: 5px solid #42A948; /* green */ } .ng-invalid:not(form) { border-left: 5px solid #a94442; /* red */ }
index.html
<!DOCTYPE html> <html> <head> <title>Hero Form</title> <script>document.write('<base href="' + document.location + '" />');</script> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="forms.css"> <!-- Polyfills --> <script src="https://unpkg.com/core-js/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.7.4?main=browser"></script> <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script> <script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script> <script> System.import('main.js').catch(function(err){ console.error(err); }); </script> </head> <body> <my-app>Loading...</my-app> </body> </html>
main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; platformBrowserDynamic().bootstrapModule(AppModule);
style.css
/* Master Styles */ h1 { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: 250%; } h2, h3 { color: #444; font-family: Arial, Helvetica, sans-serif; font-weight: lighter; } body { margin: 2em; } body, input[text], button { color: #888; font-family: Cambria, Georgia; } a { cursor: pointer; cursor: hand; } button { font-family: Arial; background-color: #eee; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; cursor: hand; } button:hover { background-color: #cfd8dc; } button:disabled { background-color: #eee; color: #aaa; cursor: auto; } /* Navigation link styles */ nav a { padding: 5px 10px; text-decoration: none; margin-right: 10px; margin-top: 10px; display: inline-block; background-color: #eee; border-radius: 4px; } nav a:visited, a:link { color: #607D8B; } nav a:hover { color: #039be5; background-color: #CFD8DC; } nav a.active { color: #039be5; } /* items class */ .items { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 24em; } .items li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .items li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .items li.selected { background-color: #CFD8DC; color: white; } .items li.selected:hover { background-color: #BBD8DC; } .items .text { position: relative; top: -3px; } .items .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; } /* everywhere else */ * { font-family: Arial, Helvetica, sans-serif; }
三:不想写的总结
Angular 表单技术利用了下列框架特性来支持数据修改、验证和更多操作:
-
Angular HTML 表单模板。
-
带有
@Component
装饰器的表单组件类。 -
通过绑定到
NgForm.ngSubmit
事件属性来处理表单提交。 -
模板引用变量,例如
#heroForm
和#name
。 -
[(ngModel)]
语法用来实现双向数据绑定。 -
name
属性的用途是有效性验证和对表单元素的变更进行追踪。 -
指向 input 控件的引用变量上的
valid
属性,可用于检查控件是否有效、是否显示/隐藏错误信息。 -
通过绑定到
NgForm
的有效性状态,控制提交按钮的禁用状态。 -
定制 CSS 类来给用户提供无效控件的视觉反馈。
- 我编不出来了!