Set null as empty string value for input field

前端 未结 3 912
囚心锁ツ
囚心锁ツ 2020-12-15 05:33

I have an input field mapped to an entity in my controller with a ngModel 2-way binding:

&         


        
3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-15 06:28

    I just formed this solution after much research. It's kind of hacky since the Angular team doesn't recommend extending DefaultValueAccessor, but it automagically works for every input without having to mark each one individually.

    import { Directive, forwardRef, Renderer2, ElementRef, Input } from '@angular/core';
    import { DefaultValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
    
    export const VALUE_ACCESSOR: any = {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => InputExtensionValueAccessor),
        multi: true
    };
    
    @Directive({
        selector: 'input:not([type]),input[type=text],input[type=password],input[type=email],input[type=tel],textarea',
        host: {
            '(input)': '_handleInput($event.target.value)',
            '(blur)': 'onTouched()',
            '(compositionstart)': '_compositionStart()',
            '(compositionend)': '_compositionEnd($event.target.value)'
        },
        providers: [VALUE_ACCESSOR]
    })
    export class InputExtensionValueAccessor extends DefaultValueAccessor  {
        // HACK: Allows use of DefaultValueAccessor as base
        // (https://github.com/angular/angular/issues/9146)
        static decorators = null;
    
        constructor(renderer: Renderer2, elementRef: ElementRef) {
            super(renderer, elementRef, (null as any));
        }
    
        registerOnChange(fn: (_: any) => void): void {
            super.registerOnChange(value => {
                // Convert empty string from the view to null for the model
                fn(value === '' ? null : value);
            });
        }
    }
    

    This is working great for me on Angular 4.4.5.

提交回复
热议问题