Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

502
Visualizações
Angular: Call markAsDirty() in Custom Input Component from NgForm

I implemented a custom component which is a wrapper for an input with NgModel. I connected them with a ControlValueAccessor. It works well, I can easily access values from my parent component.

But if I try to call markAsDirty() the touched flag is only changing on my component, it has no effect to my input inside the component. I will give you an example:

// Parent Component
onSubmit(form: NgForm) {
    this.form.controls.registerEmail.markAsDirty();
}

// Thats how the component looks like in my form:
<form #form="ngForm" (ngSubmit)="onSubmit(form)" [ngClass]="{'has-error': !form.valid}">
    <form-text label="E-Mail" name="registerEmail" email required placeholder="" [(ngModel)]="eMail"></form-text>
</form>

// Result
<form-text label="E-Mail" name="registerEmail" class="ng-untouched ng-invalid ng-dirty">
    <label for="form-text-2">E-Mail</label>
    <input class="input-control invalid ng-untouched ng-pristine ng-invalid" type="text" id="form-text-2">
</form-text>

As you can see the form-text has the "ng-dirty" class, the input inside remains pristine.

To implement my custom component I used one the many instructions you find on the web. Here is the one I used: angular2 custom form control with validation json input

I want to mark every input field as dirty when the submit button is pressed. Because my validation shows up, when you blur the input.

I figured out that there is the problem my component inherits from ControlValueAccessor. The only connection between my component and my NgForm is over its NgModel. The NgForm can use my component as FormControl because it has its own NgModel. Over events it's possible to pass values in two directions. But it's not possible with methods like markAsDirty() or markAsTouched(). Inside the component it's no problem. But my NgForm has no real access to components. Only to NgModel.

Is there any way to implement that? I thought it's not that hard to figure it out, but I am struggling for a long time with that. My only solution for the moment is to iterate over every input with jQuery to fire a focus. There must be a cleaner solution for that.

Thx

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You can pass as input in the component which implements ControlValueAccessor the dirty property of the form and then update the state of your inner input using ReactiveFormsModule and FormControl.

The component which holds your form:

<form #myForm="ngForm" (submit)="onSubmit($event)">
    <my-input name="my-input" [(ngModel)]="myInput" [formDirty]="myForm.dirty"></my-input>
    <button type="submit">Submit</button>
</form>

Then in the component which implements ControlValueAccessor:

  ngOnChanges({ formDirty }: SimpleChanges) {
    if (formDirty.currentValue) {
      this.inputCtrl.markAsDirty();
    } else {
      this.inputCtrl.markAsPristine();
    }
  }

Here you can find the relevant snippet.

over 4 years ago · Santiago Trujillo Relatório

0

You need to call onTouched() (this._onTouchedCallback) from inside your component when you want the controls status set to touched. Same for this._onChangeCallback

For example by adding (ngModelChange)="onTouched(value)" to the input tag in my-custom-input

Copied from: https://github.com/angular/angular/issues/10151

over 4 years ago · Santiago Trujillo Relatório

0

The problem is that there is no easy way to get any notification when dirty state changes. See https://github.com/angular/angular/issues/10887.

Helper directive:

@Directive({
  selector: 'my-input'
})
export class MagickDirective implements DoCheck {
  constructor(private control:NgModel){
  }
  ngDoCheck(): void {
    //you can do whatever you want
    if(this.control.dirty) {
      (this.control.valueAccessor as MyInputComponent).setDirty(true);
    }
  }
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda