幽灵自醒

导航

关于angular实现表单的一些问题

如何用angular实现表单的一些问题?核心步骤大概如下:

  1. 创建模型类

  2. 创建控制此表单的组件。

  3. 创建具有初始表单布局的模板。

  4. 使用ngModel双向数据绑定语法把数据属性绑定到每个表单输入控件。

  5. 往每个表单输入控件上添加name属性 (attribute)。

  6. 添加自定义 CSS 来提供视觉反馈。

  7. 显示和隐藏有效性验证的错误信息。

  8. 使用 ngSubmit 处理表单提交。

  9. 禁用此表单的提交按钮,直到表单变为有效。

-------------理论到此结束,我是最不华丽的分割线-----------------------------------

 

一:需要哪些文件?

一图胜千言,哈哈哈哈!!!

(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

      &nbsp;&nbsp;
      <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 类来给用户提供无效控件的视觉反馈。

  • 我编不出来了!

 

posted on 2017-03-16 00:44  幽灵自醒  阅读(173)  评论(0编辑  收藏  举报