如何在没有输入的情况下通过自定义控件以角度形式触发change() [英] How to trigger change() in a angular form by a custom control without an input

查看:40
本文介绍了如何在没有输入的情况下通过自定义控件以角度形式触发change()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实想创建一个不包含任何输入的自定义控件.每当控件更改时,我都希望保存完整的表单.

I do want to create a custom control which does not include any input. Whenever the control changes, I do want to save the complete form.

我们当前的方法使用如下形式的更改事件:

Our current approach uses the form-changed-event like this:

 <form #demoForm="ngForm" (change)="onChange()">
      <custom-input name="someValue" [(ngModel)]="dataModel">
      </custom-input>
 </form>

如您所见,我们使用"change"事件来响应表单中的任何更改.只要我们具有输入,复选框,...作为控件,此方法就可以正常工作.

As you can see, we use the "change"-event to react to any change in the form. This works fine as long as we have inputs, checkboxes, ... as controls.

但是我们的自定义控件仅存在于我们可以单击的简单div之外.每当我单击div时,控件的值都会增加1.但是不会触发表单的更改"事件.我是否必须以某种方式将我的自定义控件链接到表单?还是有任何需要触发的事件?

But our custom control does only exist out of a simple div we can click on. Whenever I click on the div the value of the control is increased by 1. But the "change"-event of the form is not fired. Do I somehow have to link my custom control to the form? Or are there any events which need to be fired?

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

@Component({
    selector: 'custom-input',
    template: `<div (click)="update()">Click</div>`,
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => CustomInputComponent),
        multi: true
    }]
})
export class CustomInputComponent implements ControlValueAccessor {

    private onTouchedCallback: () => void = () => {};
    private onChangeCallback: (_: any) => void = () => {};

    update(){
      this.value++;
    }

    get value(): any {
        return this.innerValue;
    };

    set value(v: any) {
        console.log("Change to");
        if (v !== this.innerValue) {
            this.innerValue = v;
            this.onChangeCallback(v);
        }
    }

    writeValue(value: any) {
        if (value !== this.innerValue) {
            this.innerValue = value;
        }
    }

    registerOnChange(fn: any) {
        this.onChangeCallback = fn;
    }

    registerOnTouched(fn: any) {
        this.onTouchedCallback = fn;
    }
}

我创建了一个插件来演示该问题: https://plnkr.co/edit/ushMfJfcmIlfP2U1EW6A

I've created a plunker to demonstrate the problem: https://plnkr.co/edit/ushMfJfcmIlfP2U1EW6A

每当您单击单击"时,模型值都会增加,但控制台上没有输出,因为不会触发变更事件...(有一个console.log链接到变更事件)

Whenever you click on "Click" the model-value is increased, but there is no output on the console, as the change-event is not fired... (There is a console.log linked to the change-event)

推荐答案

感谢您的答复.

最后,我找到了解决此问题的以下方法:正如Claies在评论中提到的那样,我的自定义组件不会触发更改事件.因此,表格永远不知道更改.这与角度无关,但正如所说的那样,是输入/表单的预期行为.

Finally I found the following solution to this problem: As Claies mentioned in the comment, my custom component does not fire the change event. Therfore the form does never know about the change. This has nothing todo with angular, but as said is the expected behaviour of a input/form.

最简单的解决方案是在发生更改时在customcontrol中触发更改事件:

The easiest solution is to fire the change-event in the customcontrol when a change happens:

constructor(private element: ElementRef, private renderer: Renderer) {
}

public triggerChanged(){
    let event = new CustomEvent('change', {bubbles: true});
    this.renderer.invokeElementMethod(this.element.nativeElement, 'dispatchEvent', [event]);
}

就是这样,每当我在自定义组件中调用"onControlChange(..)"时,随后我都会触发此事件.

That's it, whenever I called "onControlChange(..)" in my custom component, then I fire this event afterward.

请注意,您需要Custom-Event-Polyfill来支持IE! https://www.npmjs.com/package/custom-event-polyfill

Be aware, that you need the Custom-Event-Polyfill to support IE! https://www.npmjs.com/package/custom-event-polyfill

这篇关于如何在没有输入的情况下通过自定义控件以角度形式触发change()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆