我在这里重新创建了这个问题
https://stackblitz.com/edit/angular-custom-validator-issue
您可以分叉设置(右上角),然后根据需要进行编辑
基本上我试图在我的被动表单设置中创建一个自定义验证器,它接受表单输入的值,并向Datamuse API发送一个http请求,用于计算字符串中音节的数量。然后根据响应结果我返回错误或成功。我已经遵循了角度文档,但我的解决方案是http调用问题,我相信调用堆栈顺序。所以我需要帮助我如何实现这一目标,我认为这将有助于我更好地理解Angular。
import { Component, ElementRef } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { VERSION } from '@angular/material';
import { SyllableCountValidator } from './syllable-count.service';
@Component({
selector: 'material-app',
templateUrl: 'app.component.html'
})
export class AppComponent {
version = VERSION;
public poemForm: FormGroup;
constructor(private fb: FormBuilder, private scv: SyllableCountValidator) {
this.createForm();
}
//ERRORS APPEAR IN CONSOLE after INPUT into 'input text' in the dom
// 1. create form group with entry inputText. Initialise it with no value
// and set the validation to a custom validator called 'count' that is
// located in the 'private scv: SyllableCountValidator' service
// go to syllable-count.service file to see next steps
createForm() {
this.poemForm = this.fb.group({
inputText: ['', [this.scv.count]],
});
}
}
import { ValidatorFn, AbstractControl, FormControl } from '@angular/forms';
import { forEach } from '@angular/router/src/utils/collection';
import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class SyllableCountValidator {
constructor(private http: HttpClient) {}
// 2. create http request to datamuse API that returns a syllable
// count repsonse for requested text
public requestCount(text): Observable<Object> {
return this.http.get(`https://api.datamuse.com/words?sp=${text}&md=s`) as Observable<Object>;
}
// 3. on any input into the formControl 'inputText' this will fire
public count(control: FormControl) {
// 4. split the string received from the fromControl
// 'textInput' into an array
const arrayOfStrings = control.value.split(' ');
// 5. define empty text variable
let text = '';
// 6. loop through step 3. arrayOfStrings and concatonate into
// correct format for http call and push to text variable in step 4.
const pushToText = Array.prototype.forEach.call(arrayOfStrings, function(word) {
text = `${text}+${word}`;
});
// 7. trim first character of text variable in step 4. to remove
// unessecary '+' character
const trimmedText = text.substr(1);
// 8. call requestCount() in step 2. and return validation result
if (trimmedText) {
const validateSyllables = this.requestCount(trimmedText).subscribe((response) => {
// 8.1.1 if syllable count is greater than 5 return error
// of number of syllables it is greater by
if ( response[0].numSyllables > 5 ) {
return {
error: 5 - response[0].numSyllables
}
// 8.1.2 if syllable count is less than 5 return error
// of number of syllables it is less by
} else if ( response[0].numSyllables > 5 ) {
return {
error: 5 - response[0].numSyllables
}
// 8.1.3 if syllable count equals 5 return validation
// success as required by angular of 'null'
} else if ( response[0].numSyllables == 5 ) {
return null;
}
});
// 9.2. return validation result
return validateSyllables;
}
}
}
答案 0 :(得分:2)
你有'this'的问题没有指向正确的范围。
“简单”修复是在服务提供商中使用胖箭头功能,以确保'this'指向服务提供商:
代替:
public count(control: FormControl) {
<强>做的:强>
public count = (control: FormControl) => {
现在您的代码仍然需要解决其他问题(比如解析响应对象无效)。