gpt4 book ai didi

javascript - Angular:尝试添加验证码。错误 => 没有名称为 'captcha' 的表单控件的值访问器

转载 作者:行者123 更新时间:2023-11-30 20:05:39 25 4
gpt4 key购买 nike

因此,我遵循了有关如何将验证码添加到表单以防止垃圾邮件的教程。我按照所有步骤操作,但仍然出现以下错误:

 error inside log Error: No value accessor for form control with name: 'captcha'
at _throwError (forms.js:2139)
at setUpControl (forms.js:2008)
at FormGroupDirective.addControl (forms.js:5144)
at FormControlName._setUpControl (forms.js:5743)
at FormControlName.ngOnChanges (forms.js:5684)
at checkAndUpdateDirectiveInline (core.js:11642)
at checkAndUpdateNodeInline (core.js:13252)

我有一个响应式(Reactive)注册表单,其中我有以下元素应该是验证码和 formControl。但不幸的是我什么也没看到。

<div nbRecaptcha key="6LfNfHYUAAAAAFaa7dVi2au1tnfod-2eR3Rb2enM" formControlName="captcha"></div>

这是 nbRecaptcha 指令:

declare const grecaptcha: any;

declare global {
interface Window {
grecaptcha: any;
reCaptchaLoad: () => void
}
}

@Directive({
selector: '[nbRecaptcha]',
providers: [ReCaptchaAsyncValidator]
})
export class RecaptchaDirective implements OnInit, ControlValueAccessor, AfterViewInit {
@Input() key: string;
@Input() config: ReCaptchaConfig = {};
@Input() lang: string;

private control: FormControl;

private onChange: ( value: string ) => void;
private onTouched: ( value: string ) => void;
private widgetId: number;

constructor(
private element: ElementRef,
private ngZone: NgZone,
private injector: Injector,
private reCaptchaAsyncValidator: ReCaptchaAsyncValidator){}

ngOnInit() {
this.registerReCaptchaCallback();
this.addScript();
}

ngAfterViewInit() {
this.control = this.injector.get(NgControl).control;
this.setValidator();
}

addScript() {
let script = document.createElement('script');
const lang = this.lang ? '&hl=' + this.lang : '';
script.src = `https://www.google.com/recaptcha/api.js?onload=reCaptchaLoad&render=explicit${lang}`;
script.async = true;
script.defer = true;
document.body.appendChild(script);
}


// We need to notify the formControl that it’s valid if we get the token
// from the onSuccess function or that it’s invalid if the onExpired function is called.

onExpired() {
this.ngZone.run(() => {
this.onChange(null);
this.onTouched(null);
});
}

onSuccess( token: string ) {
this.ngZone.run(() => {
this.verifyToken(token);
this.onChange(token);
this.onTouched(token);
});
}

// these are the three methods that controlValueAccessor requires

writeValue( obj: any ): void {
}

registerOnChange( fn: any ): void {
this.onChange = fn;
}

registerOnTouched( fn: any ): void {
this.onTouched = fn;
}

private setValidator() {
this.control.setValidators(Validators.required);
this.control.updateValueAndValidity();
}

registerReCaptchaCallback() {
window.reCaptchaLoad = () => {
const config = {
...this.config,
'sitekey': this.key,
'callback': this.onSuccess.bind(this),
'expired-callback': this.onExpired.bind(this)
};
this.widgetId = this.render(this.element.nativeElement, config);
};
}

private render( element: HTMLElement, config ): number {
return grecaptcha.render(element, config);
}

verifyToken( token : string ) {
this.control.setAsyncValidators(this.reCaptchaAsyncValidator.validateToken(token))
this.control.updateValueAndValidity();
}
}

注册组件表单:

this.mySignupForm = new FormGroup({
captcha: new FormControl()
});

谁能看出我做错了什么?

最佳答案

错误没有名称为'captcha'的表单控件的值访问器。这可以通过使用 forwardRef 将指令/控件添加到所有可用 NG_VALUE_ACCESSOR 的列表来解决。您有效地扩展了 NG_VALUE_ACCESSOR 的多提供程序,以便此指令可以访问 ControlValueAccessor

@Directive({
selector: '[nbRecaptcha]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RecaptchaDirective),
multi: true
},
ReCaptchaAsyncValidator
]
})

这是一个主要工作的 example解决了该特定错误。我不得不删除您示例中的一些自定义类/配置,因为我不知道它们的确切实现。

我找不到官方documentation用于创建自定义控件,但也有一些可靠的文章讨论创建引用此必要注册的自定义控件。

希望对您有所帮助!

关于javascript - Angular:尝试添加验证码。错误 => 没有名称为 'captcha' 的表单控件的值访问器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52958954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com