0

Ich versuche, eine benutzerdefinierte Komponente in einer eckigen FormGroup verwendet werden.Benutzerdefinierte Komponente MdDatePicker in reaktiven Form verwendet

Hier ist, wie ich diese benutzerdefinierte Komponente verwenden möchten:

<form [formGroup]="form"> 
    ... 
    <app-date-picker formControlName="dateStart" 
        [isConsultation]="isConsultation" 
        [label]="'Du'" 
        [(ngModel)]="agenda.datDeb"> 
    </app-date-picker> 
    ... 
</form> 

Problem: In der Hauptkomponente (mit diesem Formular), das Modell nicht aktualisiert, wenn sich der Wert ändert in meiner benutzerdefinierten Komponente, was beinhaltet einen MdDatePicker. Obwohl ich ControlValueAccessor verwende.

Die HTML-Vorlage meiner custome Komponente:

<div class=""> 
    <span *ngIf="label">{{label}} :</span> 
    <md-form-field class="" [ngClass]="isConsultation ? 'no-icon' : 'container-input-date'"> 
     <input mdInput 
      [mdDatepicker]="pickerDebut" 
      class="consultation" 
      [(ngModel)]="theDate"> 
     <md-datepicker-toggle mdSuffix [for]="pickerDebut"></md-datepicker-toggle> 
     <md-datepicker #pickerDebut></md-datepicker> 
    </md-form-field> 
</div> 

Und hier, nachdem Sie das Typoskript Code für meine Komponente lesen:

import {Component, Input, ViewChild, forwardRef} from '@angular/core'; 
import { 
    NgModel, 
    ControlValueAccessor, 
    NG_VALUE_ACCESSOR, 
    NG_VALIDATORS, 
    FormControl, 
} from "@angular/forms"; 

export function validateDateInputFormat(c: FormControl) { 
    // Error content in case input date format is not valid 
    let err = { 
     formatError: { 
      given: c.value, 
      acceptedFormat: 'dd/MM/yyyy' 
     } 
    }; 

console.log('VALIDATE => c : ', c); 

// Control logiq 
// return c.value == null ? null : (String(c.value).match(date_regexp)) ? null : err; 
return null; 
} 

@Component({ 
    selector: 'app-date-picker', 
    templateUrl: './date-picker.component.html', 
    styleUrls: ['./date-picker.component.scss'], 
    providers: [ 
     { 
      provide: NG_VALUE_ACCESSOR, 
      useExisting: forwardRef(() => DatePickerComponent), 
      multi: true 
     }, 
     { 
      provide: NG_VALIDATORS, 
      useValue: validateDateInputFormat, 
      multi: true 
     } 
    ] 
}) 
export class DatePickerComponent implements ControlValueAccessor { 

    @Input() 
    label : string; 
    @Input() 
    isConsultation : boolean; 

    @ViewChild(NgModel) _theDate: NgModel; 

    constructor() { } 

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

    writeValue(obj: any): void { 
     console.log('writeValue => obj : ', obj); 
     if (obj) { 
      this._theDate = obj; 
     } 
    } 

    registerOnChange(fn: any): void { 
     this.onChange = fn; 
     console.log('registerOnChange => fn : ', fn); 
    } 

    registerOnTouched(fn: any): void { 
     this.onTouched = fn; 
     console.log('registerOnTouched => fn : ', fn); 
    } 

    onChange(event){ 
     console.log('onChange(event) - event => ', event); 
     this.propagateChange(event.target.value); 
    } 

    get theDate() { 
     console.log('get theDate()'); 
     return this._theDate; 
    } 

    set theDate(val) { 
     console.log('set theDate(val) - val => ', val); 
     this._theDate = val; 
     this.propagateChange(val); 
    } 
} 

Was mache ich hier falsch?

Antwort

0

Ich habe es geschafft, dies zu überwinden.

Hier ist die Antwort.

1. Problem:

@ViewChild(NgModel) _theDate: NgModel; 

ich

umgewandelt
private _theDate : string; 

2. Problem: Die onChange Methode ist nutzlos. Ich entfernte es und unten, den Finale TS-Code für meine Komponente:

import {Component, Input, ViewChild, forwardRef} from '@angular/core'; 
import { 
    NgModel, 
    ControlValueAccessor, 
    NG_VALUE_ACCESSOR, 
    NG_VALIDATORS, 
    FormControl, 
} from "@angular/forms"; 

export function validateDateInputFormat(c: FormControl) { 
    // Error content in case input date format is not valid 
    let err = { 
     formatError: { 
      given: c.value, 
      acceptedFormat: 'dd/MM/yyyy' 
     } 
    }; 

console.log('VALIDATE => c : ', c); 

// Control logiq 
// return c.value == null ? null : (String(c.value).match(date_regexp)) ? null : err; 
return null; 
} 

@Component({ 
    selector: 'app-date-picker', 
    templateUrl: './date-picker.component.html', 
    styleUrls: ['./date-picker.component.scss'], 
    providers: [ 
     { 
      provide: NG_VALUE_ACCESSOR, 
      useExisting: forwardRef(() => DatePickerComponent), 
      multi: true 
     }, 
     { 
      provide: NG_VALIDATORS, 
      useValue: validateDateInputFormat, 
      multi: true 
     } 
    ] 
}) 
export class DatePickerComponent implements ControlValueAccessor { 

    @Input() 
    label : string; 
    @Input() 
    isConsultation : boolean; 

    private _theDate: string; 

    constructor() { } 

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

    writeValue(obj: any): void { 
     console.log('writeValue => obj : ', obj); 
     if (obj) { 
      this._theDate = obj; 
     } 
    } 

    registerOnChange(fn: any): void { 
     this.propagateChange= fn; 
     console.log('registerOnChange => fn : ', fn); 
    } 

    registerOnTouched(fn: any): void { 
     this.onTouched = fn; 
     console.log('registerOnTouched => fn : ', fn); 
    } 

    get theDate() { 
     console.log('get theDate()'); 
     return this._theDate; 
    } 

    set theDate(val) { 
     console.log('set theDate(val) - val => ', val); 
     this._theDate = val; 
     this.propagateChange(val); 
    } 
} 
Verwandte Themen