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

2024-06-09

我正在尝试创建一个要在角度 formGroup 中使用的自定义组件。

以下是我想要使用此自定义组件的方式:

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

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

我的自定义组件的 HTML 模板:

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

之后您可以阅读我的组件的打字稿代码:

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

我在这里做错了什么?


我设法克服了这个问题。

答案如下。

第一个问题:

@ViewChild(NgModel) _theDate: NgModel;

我转变为

private _theDate : string;

第二个问题: onChange方法没有用。我删除了它,下面是我的组件的最终 TS 代码:

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);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反应式表单中使用的自定义组件 MdDatePicker 的相关文章

随机推荐

  • Morphia - 未在 dbObj 中找到定义的类

    我有一个相当有趣的问题 当尝试从 Mongo 实例加载模型时 Morphia 会抛出以下错误 22 17 13 WARN Class not found defined in dbObj java lang ClassNotFoundExc
  • 要求节点模块 var 或 const 的最佳方法是什么?

    当我们需要诸如express或bodyParser之类的节点模块时 我们将使用var关键字创建变量并分配模块 我们不能用const声明这样的模块 也就是说 代替这个 var express require express var app e
  • 为什么这个 Hibernate MySQL 连接是只读的?

    我有一个在 MySQL 数据库上使用 Spring 和 Hibernate 的应用程序 由于某种原因 截至过去几天 每当我尝试将任何对象保留到数据库中时 都会收到以下错误 java sql SQLException 连接是只读的 导致数据修
  • 如何制作一条带有边框的 SVG“线”?

    我有一个小 svg 小部件 其目的是显示角度列表 参见图片 现在 角度是线元素 只有描边 没有填充 但现在我想要一个 内部填充 颜色和周围的 描边 边框 我猜 line 元素无法处理这个问题 那么我应该使用什么来代替呢 请注意 线条笔划的线
  • 升级到 Wildfly 8.2 时出现错误

    我从 Wildfly 8 1 升级到 8 2 我的第一个 JSF 请求导致了这个错误 而这在之前是有效的 罪魁祸首是什么 是否需要更新任何依赖项 需要 JDK 8 吗 16 39 36 127 ERROR io undertow reque
  • 从父类返回子类

    我有一个构建器类 它从大多数方法返回自身以允许菊花链 为了使此功能适用于子类 我希望父方法返回子类的实例 以便子方法可以链接到末尾 public class BaseBuilder
  • Firestore 未检索完整的数据值

    图 1 显示了我的数据库的层次结构 我正在尝试检索课程名称 Android 品牌 斜体数据 品牌 其他 由后端 post 命令添加 其他数据通过打字添加 当只检索非斜体数据时 如屏幕截图 2 所示 我无法弄清楚为什么会发生这种情况 屏幕截图
  • 在实体框架中对连接字符串进行硬编码

    我知道很多人认为对连接信息进行硬编码是一个坏主意 但我有一个特定的情况需要这样做 请不要贬低我 因为你认为这是一个坏主意 再次 非常具体的情况 使用下面的代码 我在 LINQ 语句上收到以下错误 底层提供程序在打开时失败 我已经独立测试了连
  • 如何从 typescript 使用 npm 模块?

    我正在尝试打字稿 它在 hello world 阶段运行良好 我现在尝试使用 npm 模块 index ts import require lodash console log toUpper Hello world 这不起作用 tsc i
  • 在 C# 中将字符串转换为等效的字节十六进制

    我有一个传入的字符串68016101061B4A60193390662046804020422044204000420040402060226024676DB16我想转换成0x68 0x01 0x61 0x01 0x06 0x1B 0x4A
  • Xamarin.Forms:如何访问 ListView.GroupHeaderTemplate 中 ListView.ItemTemplate 中使用的集合?

    我需要访问 ListView GroupHeaderTemplate 中 Switch 中的 OnOff 属性 该属性位于 ListView ItemTemplate 使用的集合中 我尝试了很多方法但没有成功 有人遇到过这个问题吗 gt
  • 在 Qt 服务器上验证用户身份

    我正在尝试使用 C QtTcpSocket 为个人项目 多人国际象棋游戏 实现身份验证系统 我的朋友建议了一种验证用户的方法 但我想问是否有更简单或更好的方法 来自 Python 背景 做这个项目主要是为了加深对 C 的理解 我将发布我朋友
  • Nestjs如何控制缓存?

    最近读了nestjs的文档 从中学到了一些东西 但我发现了一些让我困惑的事情 In 技术 缓存 https docs nestjs com techniques caching 文档告诉我使用像这样的装饰器 UseInterceptors
  • “多对二”关系

    我想知道 多对二 关系 孩子可以与两个父母中的任何一个有联系 但不能与两个父母都有联系 有什么办法可以加强这一点吗 另外我想防止孩子重复输入 现实世界的例子是电话号码 用户和公司 一个公司可以有很多电话号码 一个用户可以有很多电话号码 但理
  • List 中的 TextView 被截断

    我有一个自定义 ListView 其中有一个图像视图和两个位于图像视图旁边的 TextView 底部的文本视图包含标题的描述 但它被列表切断了 http tinypic com r 28tawrc 7 http tinypic com r
  • ASP.NET MVC 2 Preview 2 - 显示目录列表而不是 home/index

    我只是下载 ASP NET MVC 2 Preview 2 创建一个新项目并运行它 但为什么它显示目录列表而不是默认页面 我使用的是 VS2008 SP1 并安装了 ASP NET MVC 1 右键单击该项目并选择特性 在下面web设置开始
  • 要在应用为主题的按钮样式中使用layout_marginLeft?

    我使用了一个属性layout marginLeft 30dip 采用为按钮定义的样式 当我为每个按钮单独应用此样式时 左边距将根据我的需要放置 但后来我定义了一个主题 将按钮样式分配给属性android buttonStyle并将其应用到我
  • 如何将 JavaScript 库包含到 Spring MVC 项目中(例如 jQuery 或 Dojo)

    我在这里阅读了超过 5 个相关主题 但无法找到答案 分步说明 到目前为止 我已经有了 STS Spring MVC 模板结构并尝试将jquery js在我的项目中的某个地方 不幸的是 没有人说它应该在哪里 那么 请说 将 jquery js
  • 应用程序操作通过应用程序操作工具插件工作,但不能在 Google Assistant 屏幕中使用语音命令

    使用相同的凭据 Android Studio Google Console 真实设备 Samsung s10 登录 并将设备语言设置为 EN US 从工具菜单中选择应用程序操作工具插件 将调用名称 todo 应用程序 和区域设置提供给 En
  • 反应式表单中使用的自定义组件 MdDatePicker

    我正在尝试创建一个要在角度 formGroup 中使用的自定义组件 以下是我想要使用此自定义组件的方式