2017-09-27 5 views
0

threeNumbers이라는 사용자 정의 유효성 검사기를 만들었는데 3 자리 숫자 만 허용한다는 것입니다. 나는 username 필드에 적용 할 때 그러나 당신은 단지 this.fb.group에 대한 참조로 전달, threeNumbers를 호출 할 필요는 없습니다, 오류 ERROR TypeError: Cannot read property 'length' of null 및 내장 유효성 검사기처럼 formGroup expects a FormGroup instance. Please pass one in.왜 사용자 정의 유효성 검사기가 작동하지 않습니다

ngOnInit() { 
    // form controls validation specicified in the class for the Reactive Forms 
    this.courseForm = this.fb.group({ 
     username: [null, [Validators.required, this.threeNumbers.bind(this)]], 
     email: [null, [Validators.required, Validators.pattern('([a-zA-Z0-9_.-]+)@([a-zA-Z0-9_.-]+)\\.([a-zA-Z]{2,5})')]], 
     address: [null, [Validators.required, Validators.minLength(10), Validators.maxLength(100)]], 
     select: [null, [Validators.required]] 
    }); 
    this.dropDownArr = this.dropdown.getData(); 
    // this.personDetail = { 
    // name: '', 
    // email: '', 
    // address: '', 
    // chosenCourse: '' 
    // }; 
    this.personDetail = this.fieldData.getPersonData(); 
    console.log(this.courseForm); 
    } 

    threeNumbers(control: FormControl) { 
    if (control.value.length < 3 && typeof control.value !== 'number') { 
     return { 'greater than 3 numbers': true }; 
    } 
    return null; 
    } 

//HTML template 

<!-- Form with three inputs and one dropdown which intializes with data from service on intialization and validates with min and maxlength--> 
<section class="container"> 
    <!-- ngSubmit calls the function onSubmit on submitting the form --> 
    <form class="form-horizontal" (ngSubmit)='onSubmit()' [formGroup]='courseForm'> 
    <div class="form-group"> 
     <label for="inputUsername" class="col-sm-2 control-label">Username</label> 
     <div class="col-sm-10"> 
     <input type="text" class="form-control" id="inputUsername" placeholder="Username" formControlName="username" name="name" 
      [ngClass]="{inValid: !courseForm.get('username').valid && courseForm.get('username').touched, valid: courseForm.get('username').valid && courseForm.get('username').touched}"> 
     <span class="help-block" *ngIf="!courseForm.get('username').valid && courseForm.get('username').touched">Please enter a valid username</span> 
     </div> 
    </div> 
    <!-- username input ends here --> 
    <div class="form-group"> 
     <label for="inputEmail" class="col-sm-2 control-label">Email</label> 
     <div class="col-sm-10"> 
     <!-- CSS class applied based on validation --> 
     <input type="email" class="form-control" id="inputEmail" placeholder="Email" formControlName="email" name="email" [ngClass]="{inValid: !courseForm.get('email').valid && courseForm.get('email').touched, valid: courseForm.get('email').valid && courseForm.get('email').touched}"> 
     <span class="help-block" *ngIf="!courseForm.get('email').valid && courseForm.get('email').touched">Please Enter a valid email</span> 
     </div> 
    </div> 
    <!-- email input ends here --> 
    <div class="form-group"> 
     <label for="inputAddress" class="col-sm-2 control-label">Address</label> 
     <div class="col-sm-10"> 
     <input type="text" class="form-control" id="inputAddress" placeholder="Your Address" formControlName="address" name="address" 
      [ngClass]="{inValid: !courseForm.get('address').valid && courseForm.get('address').touched, valid: courseForm.get('address').valid && courseForm.get('address').touched}"> 
     <!--Display error message on MinLength and MaxLength Validation--> 
     <span class="help-block" *ngIf="courseForm.get('address')?.errors?.required && courseForm.get('address').touched">Please Enter Your Address</span> 
     <span class="help-block" *ngIf="(courseForm.get('address')?.errors?.minlength?.requiredLength !== courseForm.get('address')?.errors?.minlength?.actualLength) && courseForm.get('address')?.touched">Address should be at least 10 characters long</span> 
     </div> 
    </div> 
    <!-- address input ends here --> 
    <div class="form-group"> 
     <label for="sel1" class="col-sm-2 control-label">Choose Course</label> 
     <div class="col-sm-10"> 
     <select class="form-control" id="sel1" formControlName="select" [(ngModel)]="selectedOption" name="select" [ngClass]="{inValid: !courseForm.get('select').valid && courseForm.get('select').touched, valid: courseForm.get('select').valid && courseForm.get('select').touched}"> 
      <option [value]="selectedOption" [disabled]="true">Choose Your Course</option> 
      <option *ngFor="let data of dropDownArr; index as i" [ngValue]="data.course">{{data.course}}</option>   
     </select> 
     <span class="help-block" *ngIf="!courseForm.get('select').valid && courseForm.get('select').touched">Please choose a Course</span> 
     </div> 
    </div> 
    <!-- select input ends here --> 
    <div class="form-group"> 
     <div class="col-sm-offset-2 col-sm-10"> 
     <button type="submit" class="btn btn-default" [disabled]=!courseForm.valid>Submit</button> 
     <button type="button" class="btn btn-default" (click)="resetForm(f)">Reset</button> 
     </div> 
    </div> 
    <!-- submit and reset buttons ends here --> 
    </form> 
</section> 
<!-- section displays the submited form data in the view --> 
<section class="container"> 
    <div class="panel panel-default"> 
    <div class="panel-heading">Registered users</div> 

    <!-- List group --> 
    <ul class="list-group"> 
     <li class="list-group-item" *ngFor="let person of personsList">username:&nbsp;&nbsp;{{person.name}} &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; email:&nbsp;&nbsp;{{person.email}} 
     &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; Address: &nbsp;&nbsp;{{person.address}} &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; 
     Course Chosen: &nbsp;&nbsp;{{person.chosenCourse}}</li> 
    </ul> 
    </div> 
</section> 
+0

템플릿을 추가 할 수 있습니까? – yurzui

+0

[Custom Validators] (https://angular.io/guide/form-validation#custom-validators) docs. –

+0

당신이'null '값을 확인하기 위해 neet을 사용한다면'control.value && control.value.length <3 ...' – yurzui

답변

0

를 던졌습니다 :

Angular가 this를 내부 호출하기 때문에 bind 호출이 필요하지 않습니다. 로 변경 : 순간

this.courseForm = this.fb.group({ 
    username: ['', [Validators.required, this.threeNumbers]], 
    email: ['', [Validators.required, Validators.pattern('([a-zA-Z0-9_.-]+)@([a-zA-Z0-9_.-]+)\\.([a-zA-Z]{2,5})')]], 
    address: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(100)]], 
    select: ['', [Validators.required]] 
}); 

, 당신은 this 속성을 결합하고 있습니다. 이 경우 this은 클래스의 인스턴스화 된 버전을 나타냅니다.

괄호를 제거하십시오.

유효성 검사기가 로컬 변수에 의존해서는 안되기 때문에 추가로 이동하여 threeNumbers 메서드를 정적으로 만들 수 있습니다. 각도 기본 유효성 검사기는 정적입니다.

public static ThreeNumbers(control: FormControl) { 
    if (control.value.length < 3 && typeof control.value !== 'number') { 
    return { 'greater than 3 numbers': true }; 
    } 
    return null; 
} 

또한 각 컨트롤 초기화에 빈 문자열 ''를 전달하는 대신 null 추천 할 것입니다. 이는 일관된 상태를 유지하는 데 도움이됩니다. N.b. 이 노트에 'typeof'체크가 있습니다.이 FormControl이 입력에 바인딩되어 있다면 typeof은 항상 문자열입니다.

나는 보상을 만들었습니다.