反应式中使用的自定义组件

反应式中使用的自定义组件

本文介绍了反应式中使用的自定义组件 MdDatePicker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个用于角度 formGroup 的自定义组件.

这是我想如何使用这个自定义组件:

...<app-date-picker formControlName="dateStart"[isConsultation]="isConsultation"[标签]="'杜'"[(ngModel)]="agenda.datDeb"></app-date-picker>...</表单>

问题:在主要组件(包含此表单)中,当我的自定义组件中的值更改时,模型不会更新,这涉及 MdDatePicker.虽然我使用的是 ControlValueAccessor.

我的客户组件的 HTML 模板:

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

在这里你可以阅读我的组件的打字稿代码:

import {Component, Input, ViewChild, forwardRef} from '@angular/core';进口 {吴模型,控制值访问器,NG_VALUE_ACCESSOR,NG_VALIDATORS,表单控件,来自@angular/forms";导出函数 validateDateInputFormat(c: FormControl) {//输入日期格式无效时的错误内容让错误 = {格式错误:{给定:c.value,接受格式:'dd/MM/yyyy'}};console.log('VALIDATE => c : ', c);//控制逻辑//返回 c.value == null ?null : (String(c.value).match(date_regexp)) ?空:错误;返回空;}@成分({选择器:'应用程序日期选择器',templateUrl: './date-picker.component.html',styleUrls: ['./date-picker.component.scss'],供应商: [{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => DatePickerComponent),多:真},{提供:NG_VALIDATORS,使用值:validateDateInputFormat,多:真}]})导出类 DatePickerComponent 实现 ControlValueAccessor {@输入()标签:字符串;@输入()isConsultation : 布尔值;@ViewChild(NgModel) _theDate: NgModel;构造函数(){}传播变化 = (_: 任何) =>{};onTouched: any = () =>{ };writeValue(obj: any): void {console.log('writeValue => obj : ', 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(事件){console.log('onChange(event) - event => ', event );this.propagateChange(event.target.value);}获取日期(){console.log('get theDate()');返回 this._theDate;}设置日期(val){console.log('set theDate(val) - val => ', val );this._theDate = val;this.propagateChange(val);}}

我在这里做错了什么?

解决方案

我设法克服了这个问题.

这是答案.

第一个问题:

@ViewChild(NgModel) _theDate: NgModel;

我变成了

private _theDate : string;

第二个问题:onChange 方法没用.我删除了它和下面,我的组件的结局 TS 代码:

import {Component, Input, ViewChild, forwardRef} from '@angular/core';进口 {吴模型,控制值访问器,NG_VALUE_ACCESSOR,NG_VALIDATORS,表单控件,来自@angular/forms";导出函数 validateDateInputFormat(c: FormControl) {//输入日期格式无效时的错误内容让错误 = {格式错误:{给定:c.value,接受格式:'dd/MM/yyyy'}};console.log('VALIDATE => c : ', c);//控制逻辑//返回 c.value == null ?null : (String(c.value).match(date_regexp)) ?空:错误;返回空;}@成分({选择器:'应用程序日期选择器',templateUrl: './date-picker.component.html',styleUrls: ['./date-picker.component.scss'],供应商: [{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => DatePickerComponent),多:真},{提供:NG_VALIDATORS,使用值:validateDateInputFormat,多:真}]})导出类 DatePickerComponent 实现 ControlValueAccessor {@输入()标签:字符串;@输入()isConsultation : 布尔值;私人_theDate:字符串;构造函数(){}传播变化 = (_: 任何) =>{};onTouched: any = () =>{ };writeValue(obj: any): void {console.log('writeValue => obj : ', 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);}获取日期(){console.log('get theDate()');返回 this._theDate;}设置日期(val){console.log('set theDate(val) - val => ', val );this._theDate = val;this.propagateChange(val);}}

I am trying to create a custom component to be used in a angular formGroup.

Here's is how I want to use this custom component:

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

Problem : In the main component (containing this form), The model doesn't get updated when the value changes in my custom component, which is involving a MdDatePicker. Though I am using ControlValueAccessor.

The HTML template of my custome component :

<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>

And here after you can read the typescript code for my component :

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);
    }
}

What am I doing wrong here ?

解决方案

I managed to overcome this.

Here's the answer.

1st problem :

@ViewChild(NgModel) _theDate: NgModel;

I transformed to

private _theDate : string;

2nd problem :The onChange methode is useless. I removed it and below, the finale TS code for my component:

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);
    }
}

这篇关于反应式中使用的自定义组件 MdDatePicker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:13