首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有FormControl模糊的角自定义updateOn

带有FormControl模糊的角自定义updateOn
EN

Stack Overflow用户
提问于 2021-12-01 02:44:05
回答 1查看 1.9K关注 0票数 3

我有一个反应性表单组,它可以很好地处理updateOn、、submit、和updateOn change

但是,当我切换到updateOn 时,所需的错误将在我的自定义窗体控件中输入一个字符后直接触发,并且永远不会消失。而且,当我提交我的表单时,我的自定义表单控件的所有值都是空的(即使fiels已经完成)。

My form TS:

代码语言:javascript
复制
activityForm = this.fb.group({
    placeName: ['', { validators: [Validators.required, Validators.maxLength(75)] }],
    description: ['', { validators: [Validators.required, Validators.minLength(25), Validators.maxLength(2000)] }],
  }, { updateOn: 'blur' })

我的表单HTML:

代码语言:javascript
复制
<form class="container" [formGroup]="activityForm" (ngSubmit)="onSubmit()">

    <div class="container__field">
        <p class="container__title">{{'poi.place_name' | transloco}}</p>
        <custom-input formControlName="placeName" placeholder="{{'poi.select_place_name' | transloco}}" [error]="activityForm.get('placeName')?.errors !== null && activityForm.get('placeName')!.touched"></custom-input>
        <custom-error [text]="'error.required' | transloco" *ngIf="activityForm.get('placeName')?.hasError('required') && activityForm.get('placeName')?.touched"></custom-error>
        <custom-error [text]="'error.maxlength' | transloco : { charact : this.activityForm.get('placeName')?.errors?.maxlength.requiredLength }" *ngIf="activityForm.get('placeName')?.hasError('maxlength')"></custom-error>
    </div>

    <div class="container__field">
        <p class="container__title">{{'poi.description' | transloco}}</p>
        <custom-textarea formControlName="description" placeholder="{{'poi.select_description' | transloco}}" [limit]="2000" [error]="activityForm.get('description')?.errors !== null && activityForm.get('description')!.touched"></custom-textarea>
        <custom-error [text]="'error.required' | transloco" *ngIf="activityForm.get('description')?.hasError('required') && activityForm.get('description')?.touched"></custom-error>
        <custom-error [text]="'error.maxlength' | transloco : { charact : this.activityForm.get('description')?.errors?.maxlength.requiredLength }" *ngIf="activityForm.get('description')?.hasError('maxlength')"></custom-error>
        <custom-error [text]="'error.minlength' | transloco : { charact : this.activityForm.get('description')?.errors?.minlength.requiredLength }" *ngIf="activityForm.get('description')?.hasError('minlength')"></custom-error>
    </div>

    <div class="container__button">
        <custom-button text="{{'poi.next_step' | transloco}}" color="primary" type="submit"></custom-button>
    </div>
</form>

自定义FormControl TS ( textarea 1):

代码语言:javascript
复制
export class CustomTextareaComponent implements ControlValueAccessor {

  @Input() placeholder = '' // give a transloco string directly
  @Input() limit = 500
  @Input() error: boolean = false

  value: string | null = null
  currentNumberOfCharacters: number = 0
  isActive: boolean | undefined

  onChange: any = () => { }
  onTouch: any = () => { }
  touched = false
  disabled = false
  
  changes(event: Event) {
    if (this.disabled) return
    this.markAsTouched()
    this.value = event?.target ? (event?.target as HTMLTextAreaElement).value : ''
    this.currentNumberOfCharacters = this.value.length
    this.onChange(this.value)
  }


  /* Methods needed by ControlValueAccessor to transform this component into a "form friendly" component */

  registerOnChange(providedFunction: any) {
    this.onChange = providedFunction
  }

  registerOnTouched(providedFunction: any) {
    this.onTouch = providedFunction
  }

  writeValue(providedValue: any) {
    if (providedValue) {
      this.value = providedValue
      this.currentNumberOfCharacters = providedValue.length
    }
  }

  setDisabledState(providedDisabledVal: any) {
    this.disabled = providedDisabledVal
  }

  markAsTouched() {
    if (!this.touched) {
      this.onTouch()
      this.touched = true
    }
  }

}

自定义FormControl HTML ( textarea 1):

代码语言:javascript
复制
<div class="plnd-textarea">
    <div class="plnd-textarea__field-container" [class.plnd-textarea__field-container--written]="value" [class.plnd-textarea__field-container--active]="isActive" [class.plnd-textarea__field-container--error]="error">
        <textarea [placeholder]="placeholder | transloco" [value]="value" (keyup)="changes($event)" (focus)="isActive=true" (focusout)="isActive=false" [maxLength]="limit" class="plnd-textarea__field"></textarea>
    </div>
    <p class="plnd-textarea__characters">{{ currentNumberOfCharacters }}/{{ limit }} {{ 'common.characters' | transloco }}</p>
</div>

因此,我的问题是:如何使updateOn 模糊与自定义FormControl一起工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-01 07:48:01

你实际上错过了模糊事件。代码中似乎也有很多杂音,不知道active是用来做什么的。以下是一个经过清理的版本:

模板:

代码语言:javascript
复制
<textarea [value]="value" (blur)="onBlur()" (keyup)="changes($event)"></textarea>

和TS:

代码语言:javascript
复制
value: string | null = null;
onChange: any = () => {};
onTouch: any = () => {};
disabled = false;

changes(event: Event) {
  if (this.disabled) return;
  this.value = event?.target
  ? (event?.target as HTMLTextAreaElement).value
  : '';
  this.onChange(this.value);
}

onBlur() {
  this.onTouch();
}
registerOnChange(providedFunction: any) {
  this.onChange = providedFunction;
}

registerOnTouched(providedFunction: any) {
  this.onTouch = providedFunction;
}

writeValue(providedValue: any) {
  this.value = providedValue;
}

setDisabledState(providedDisabledVal: any) {
  this.disabled = providedDisabledVal;
}

此外,您还需要从markAsTouched()函数中删除onChange,因为否则键入时会立即显示错误,因为字段被触及,并且您已经更新了模糊,这意味着在发生模糊事件之前,值不会更改。

这里有一个演示供您参考

此外,您还可以查看下面的文章,而不是在实现ControlValueAccessor时重新发明轮子

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70178531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档