Angular2 +验证中的Checkbox指令

时间:2016-09-15 00:53:31

标签: angular angular2-directives angular2-forms angular2-formbuilder

在我的应用程序中,我有许多不同的形式,其中一些有复选框 这就是为什么我决定为他们创建checkbox-es +自定义验证器的指令。

在这个指令中我使用的是DoCheck,但也许这不是Angular2创建这种表单指令的方法。一切都正常,但我认为有一个更好的方法来创建复选框/按钮窗体指令。

在Angular2表单API中,我发现有http://symfony.com/doc/current/assetic/asset_management.html指令和CheckboxControlValueAccessor接口。也许我应该用它们?如果是,是否有任何示例如何使用它?

我的问题是:这是为Angular2表单创建复选框指令的正确方法吗?

以下是我的解决方案ControlValueAccessor

的示例

app.ts

import {Component, OnInit, NgModule, ViewEncapsulation} from '@angular/core'
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser'
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'
import { ValidatedMulticheckboxComponent } from 'src/directives/validated-multicheckbox.component'
import { CustomValidatorsService } from 'src/services/custom-validator.service.ts'

@Component({
  selector: 'my-app',
  templateUrl: 'src/app.html',
  styleUrls: ['src/app.css'],
  encapsulation: ViewEncapsulation.None
})
export class App implements OnInit {
  colorOptions:Array<string> = ["red", "green", "blue"];

  constructor(public fb: FormBuilder, private cvs: CustomValidatorsService) {
  }

  ngOnInit() {
    this.myForm = this.fb.group({
      userName: ['', Validators.compose([Validators.required])],
      colors: new FormArray([], Validators.compose([this.cvs.requiredArray]))
    })
  }

}

@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule ],
  declarations: [ App, ValidatedMulticheckboxComponent ],
  providers: [ CustomValidatorsService ]
  bootstrap: [ App ]
})
export class AppModule {}

app.html

<div>
  <h2>Checkbox validation</h2>
</div>
<form [formGroup]="myForm" novalidate>
  <div class="form-group">
    <label for="userName">User name</label>
    <input type="text" class="form-control" id="userName" name="userName" formControlName="userName"/>
  </div>
   <div class="form-group">
      <validated-multicheckbox [control]="myForm.controls['colors']" [options]="colorOptions"
        [model]="myForm.controls['colors']" >
        <label for="colors">Select your colors</label>
      </validated-multicheckbox>
    </div>
</form>

<pre>Is myForm valid?: <br>{{myForm.valid | json}}</pre>
<pre>form value: <br>{{myForm.value | json}}</pre>

指令/验证-multicheckbox.component.ts

import { Component, Input, DoCheck } from '@angular/core'
import { FormArray, FormControl } from '@angular/forms'
import { CustomValidatorsService } from 'src/services/custom-validator.service.ts'

@Component({
  selector: 'validated-multicheckbox',
  templateUrl: 'src/directives//validated-multicheckbox.component.html'
})
export class ValidatedMulticheckboxComponent implements DoCheck {

  @Input() control: FormControl = new FormControl();
  @Input() options: any;
  @Input() model: any;

  private errorMessages: Array<string> = [];
  private isValid: boolean;
  numberOfClicks:number = 0;

  constructor(private svc: CustomValidatorsService) {   }

  ngDoCheck() {
    this.errorMessages = this.svc.buildErrorMessages(this.control);
    this.isValid = this.errorMessages.length === 0;
  }

  public hasOption(option): boolean {
    return (this.model.value.indexOf(option) > -1);
  }

  changeCheckbox(option: any) {  
    this.numberOfClicks++;
    var currentScheduleControls: FormArray = this.model as FormArray;
    var index = currentScheduleControls.value.indexOf(option);
    if (index > -1) currentScheduleControls.removeAt(index);
    else currentScheduleControls.push(new FormControl(option)); 
  }

}

指令/验证-multicheckbox.component.html

<div class="form-group">
  <ng-content></ng-content>
  <div class="row">
    <div class="col-xs-12 col-sm-6" *ngFor="let option of options">
       <label ><input type="checkbox" (change)="changeCheckbox(option)" [checked]="hasOption(option)" [value]="option" />{{option}}</label>
    </div>
  </div>
  <div [hidden]="isValid || numberOfClicks === 0" class="alert alert-danger">
    <div *ngFor="let errMsg of errorMessages">
      {{errMsg}}
    </div>
  </div>
</div>

服务/定制validator.service.ts

import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

const requireMessage = 'The field is required'; 

@Injectable()
export class CustomValidatorsService {

  private errorMessage: Array<string>;

  constructor() { }

  requiredArray(control:FormControl){
    return (control.value.length > 0) ? null : {'required' : true};
  }

  buildErrorMessages( control: FormControl){

    this.errorMessage = [];

    this.buildControlErrorMessages(control);

    return this.errorMessage;
  }

  buildControlErrorMessages(control: FormControl){
    if(control.hasError('required')){
      this.errorMessage.push(requireMessage);
    }

  }

}

0 个答案:

没有答案