Угловой ControlValueAccessor обязательный атрибут

У меня есть элемент управления текстовым полем, который реализует ControlValueAccessor. В форме я помещаю требуемый валидатор в имя поля формы:

 this.formGroup = this.fb.group({
        name: ['', Validators.required]
    });

В шаблоне я использую такой элемент управления:

<input-text formControlName="name"></input>

Требуемая проверка Angular работает, но внутреннее текстовое поле не имеет обязательного атрибута. Я хочу стилизовать это текстовое поле, если это необходимо, как мне это сделать?


person Mcanic    schedule 23.10.2018    source источник
comment
Вы пробовали решение для инжектора: stackoverflow.com/a/51126965/8945135   -  person ibenjelloun    schedule 23.10.2018
comment
попробовал, и да, теперь я могу проверить массив ошибок, но я хочу знать заранее, требуется ли это поле, если оно еще не проверено, а также было ли оно проверено и достоверно. как я могу узнать внутри реализации ControlValueAccessor, есть ли у элемента управления требуемый валидатор?   -  person Mcanic    schedule 23.10.2018
comment
Я думаю, вам не следует думать о том, какие ошибки у вас внутри компонента, вам просто нужно проверить, есть ли ошибки (обязательные или другие ошибки проверки) и изменить стиль компонента. Таким образом, ваш компонент является универсальным и может использоваться в других сценариях использования с другими валидаторами.   -  person ibenjelloun    schedule 23.10.2018


Ответы (2)


Если вы хотите стилизовать поле, если для элемента управления есть требуемый валидатор, вы можете использовать эту утилиту:

  isRequired(formControl: AbstractControl): boolean {
    return this.hasRequiredField(formControl);
  }
  hasRequiredField = (abstractControl: AbstractControl): boolean => {
    // caso formControl
    if (abstractControl.validator) {
      const validator = abstractControl.validator({} as AbstractControl);
      if (validator && validator.required) {
        return true;
      }
    } // caso formGroup
    if (abstractControl['controls']) {
      for (const controlName in abstractControl['controls']) {
        if (abstractControl['controls'][controlName]) {
          if (this.hasRequiredField(abstractControl['controls'][controlName])) {
            return true;
          }
        }
      }
    }
    return false;
  }

в вашем контроллере

isRequired(formControlName){
    isRequired(formControlName: string): boolean {
        return this.utils.isRequired(this.form.get(formControlName));
    }
}

если вы хотите показать сообщение, когда поле недействительно, и применить стиль, вы можете использовать просто "действительное" свойство. Для отображения ошибки сообщения, когда поле недействительно, объект возвращается в hasError ('required')

Теперь, если вы хотите стилизовать

<label> Name {{isRequired('name') ? '*' :'' }} </label>
<input-text formControlName="name" [ngClass]="{'required': isRequired('name'), 'notValid' : !this.form.get('name').valid  }"></input>

<span class="help-block error" *ngIf="((form.get('name').touched || form.get('name').dirty) && !form.get('name').valid)">
        <span *ngIf="form.get('name').hasError('required')">
            {{ 'ERROR_MSG.REQUIRED' | translate }}
        </span>
        <span *ngIf="form.get('name').hasError('maxlength')">
            {{ 'ERROR_MSG.MAXLENGTH' | translate }} {{getError('maxlength').requiredLength}}
        </span>
        <span *ngIf="form.get('name').hasError('minlength')">
            {{ 'ERROR_MSG.MINLENGTH' | translate }} {{getError('minlength').requiredLength}}
        </span>

        <span *ngIf="form.get('name').hasError('myCustomError')">
            {{ 'ERROR_MSG.CUSTOM' | translate }}
        </span>
    </span>
</div>

getError(error: string) {
    return this.form.controls['name'].errors[error];
  }
person raffaeleambrosio    schedule 09.04.2019

Вам необходимо проверить изменение значения элемента управления формой, как показано ниже.

this.control.valueChanges.subscribe(
            (res) => {
                this.setErrorMessage(this.control);
            }
        )

А затем внутри setErrorMessage проверьте control.errors

if (control.errors) {
  for (let propertyName in control.errors) {
    if(propertyName == "required") {
      // you can do things here to your input field by using element reference
    }
  }
}

У меня была создана функция, чтобы знать, является ли поле ввода грязью = y или нет

//Validate single field
export function isInputFieldDirty(controlName: string, formGroupObject: FormGroup) {
if (formGroupObject.get(controlName)) {
    return !formGroupObject.get(controlName).pristine &&
        ((formGroupObject.get(controlName).untouched && formGroupObject.get(controlName).dirty && formGroupObject.get(controlName).invalid) ||
            (formGroupObject.get(controlName).touched && formGroupObject.get(controlName).invalid))
        ? true : false;
}

}

person djain4    schedule 23.10.2018
comment
Пожалуйста, дайте мне знать, почему он устарел ?? - person djain4; 23.10.2018
comment
Спасибо, я могу проверить массив ошибок, но я хочу знать заранее, требуется ли это поле, если оно еще не проверено, а также было ли оно проверено и допустимо. как я могу узнать внутри реализации ControlValueAccessor, есть ли у элемента управления требуемый валидатор? - person Mcanic; 23.10.2018
comment
Чтобы проверить, действителен ли элемент управления, вы можете использовать control.valid. Я не уверен насчет ControlValueAccessor. Также почему вы хотите знать о валидаторах на элементе управления? Я добавил функцию, посмотрите, помогает ли это - person djain4; 23.10.2018
comment
Потому что я хочу как-то показать, какие поля являются обязательными, как только форма отображается. В противном случае пользователь должен сначала нажать кнопку «Сохранить», а затем обнаружит, что некоторые поля являются обязательными. Я думаю, что лучше заранее указать, какие поля требуются. Я ошибаюсь? - person Mcanic; 23.10.2018
comment
Да, вы правильно думаете, проверьте эту ссылку: github.com/angular/angular/issues/ 13461, в этом Rodolfojnn дал решение, вы можете изменить его в соответствии с вашими потребностями - person djain4; 23.10.2018