2017-09-22 4 views
1

J'ai implémenté un contrôle de formulaire personnalisé via des formulaires guidés par template qui enveloppe une entrée en html et ajoute une étiquette, etc. Il parle à la forme juste avec la liaison de données 2way sur le ngModel. Le problème est que le formulaire est automatiquement marqué comme sale lorsqu'il est initialisé. Existe-t-il un moyen d'empêcher que cela se produise afin que je puisse utiliser ces propriétés sur le formulaire et qu'elles seront précises?Angular4 Exclure la propriété de la vérification

sélecteur sur mesure (Cela fonctionne bien autre que d'être automatiquement sale marquée):

<form class="custom-wrapper" #searchForm="ngForm"> 
 
      {{searchForm.dirty}} 
 
      {{test}} 
 
      <custom-input name="testing" id="test" label="Hello" [(ngModel)]="test"></custom-input> 
 
      <pre>{{ searchForm.value | json }}</pre> 
 
</form>

modèle d'entrée personnalisée:

<div class="custom-wrapper col-xs-12"> 
 
    <div class="row input-row"> 
 
     <div class="col-xs-3 col-md-4 no-padding" *ngIf="!NoLabel"> 
 
      <label [innerText]="label" class="inputLabel"></label> 
 
     </div> 
 
     <div class="col-xs-9 col-md-8 no-padding"> 
 
      <input pInput name="cust-input" [(ngModel)]="value" /> 
 
     </div> 
 
    </div> 
 
</div>

Composante d'entrée personnalisée:

import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; 
 
import { Component, Input, forwardRef } from "@angular/core"; 
 

 
@Component({ 
 
    selector: "custom-input", 
 
    template: require("./custom-input.component.html"), 
 
    providers: [ 
 
     { 
 
      provide: NG_VALUE_ACCESSOR, 
 
      useExisting: forwardRef(() => QdxInputComponent), 
 
      multi: true 
 
     } 
 
    ] 
 
}) 
 

 
export class CustomInputComponent implements ControlValueAccessor { 
 
    @Input("value") _value = ""; 
 
    get value() { 
 
     return this._value; 
 
    } 
 
    set value(val: string) { 
 
     this._value = val; 
 
     this.propagateChange(val); 
 
    } 
 
    @Input() noLabel: boolean = false; 
 
    @Input() label: string = "Label required"; 
 
    
 
    propagateChange = (_: any) => {}; 
 

 
    writeValue(value) { 
 
     if (value !== undefined) { 
 
      this.value = value; 
 
     } 
 
    } 
 
    registerOnChange(fn) { 
 
     this.propagateChange = fn; 
 
    } 
 
    registerOnTouched(fn) {} 
 

 
}

Répondre

2

vous propagez votre changement qui est la raison pour laquelle il est marqué sale. Il suffit d'adapter votre fonction writeValue de ne pas propager le changement, car logiquement, il ne devrait pas créer un changement:

export class CustomInputComponent implements ControlValueAccessor { 
    @Input("value") _value = ""; 
    get value() { 
     return this._value; 
    } 
    set value(val: string) { 
     this._value = val; 
     this.propagateChange(val); 
    } 
    @Input() noLabel: boolean = false; 
    @Input() label: string = "Label required"; 

    propagateChange = (_: any) => {}; 

    writeValue(value) { 
     if (value !== undefined) { 
      this._value = value; 
     } 
    } 
    registerOnChange(fn) { 
     this.propagateChange = fn; 
    } 
    registerOnTouched(fn) {} 

} 

Peu de temps: utiliser this._value au lieu de this.value dans votre writeValue

+1

Oui! Merci .. Je suppose que j'avais juste besoin d'un autre regard. Je vous remercie. – Bohms27

+0

Will mark répondu quand je peux! – Bohms27

+0

@ Bohms27 vous devriez déjà pouvoir, vous avez même assez de points pour upvote – smnbbrv

0

Je résolu que juste avec une directive d'attribut:

import { Directive } from '@angular/core'; 
import { NgControl } from '@angular/forms'; 

@Directive({ 
    selector: '[ignoreDirty]' 
}) 

export class IgnoreDirtyDirective { 
    constructor(private control: NgControl) { 
     this.control.valueChanges.subscribe(v => { 
      if (this.control.dirty) { 
       this.control.control.markAsPristine(); 
      } 
     }); 
    } 
} 

Et vous pouvez l'utiliser dans votre code d'une manière comme ceci:

<input ignoreDirty type="text" name="my-name" [(ngModel)]="myData">