【问题标题】:Angular4 Exclude Property from dirty checkAngular4从脏检查中排除属性
【发布时间】:2018-03-04 04:53:54
【问题描述】:

我已经通过模板驱动的表单实现了一个自定义表单控件,该表单将输入包装在 html 中并添加标签等。它可以通过 ngModel 上的 2way 数据绑定很好地与表单对话。问题是,表单在初始化时会自动标记为脏。有没有办法防止这种情况发生,这样我就可以在表单上使用这些属性并且它们是准确的?

自定义选择器(除了自动被标记为脏之外,这很好用):

<form class="custom-wrapper" #searchForm="ngForm">
            {{searchForm.dirty}}
            {{test}}
            <custom-input name="testing" id="test" label="Hello" [(ngModel)]="test"></custom-input>
            <pre>{{ searchForm.value | json }}</pre>
</form>

自定义输入模板:

<div class="custom-wrapper col-xs-12">
    <div class="row input-row">
        <div class="col-xs-3 col-md-4 no-padding" *ngIf="!NoLabel">
            <label [innerText]="label" class="inputLabel"></label>
        </div>
        <div class="col-xs-9 col-md-8 no-padding">
            <input pInput name="cust-input" [(ngModel)]="value"  />
        </div>
    </div>
</div>

自定义输入组件:

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

@Component({
    selector: "custom-input",
    template: require("./custom-input.component.html"),
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => QdxInputComponent),
            multi: true
        }
    ]
})

export class CustomInputComponent implements ControlValueAccessor {
    @Input("value") _value  = "";
    get value() {
        return this._value;
    }
    set value(val: string) {
        this._value = val;
        this.propagateChange(val);
    }
    @Input() noLabel: boolean = false;
    @Input() label: string = "Label required";
    
    propagateChange = (_: any) => {};

    writeValue(value) {
        if (value !== undefined) {
            this.value = value;
        }
    }
    registerOnChange(fn) {
        this.propagateChange = fn;
    }
    registerOnTouched(fn) {}

}

【问题讨论】:

    标签: angular angular2-forms angular4-forms


    【解决方案1】:

    我只是用一个属性指令解决了这个问题:

    import { Directive } from '@angular/core';
    import { NgControl } from '@angular/forms';
    
    @Directive({
        selector: '[ignoreDirty]'
    })
    
    export class IgnoreDirtyDirective {
        constructor(private control: NgControl) {
            this.control.valueChanges.subscribe(v => {
                if (this.control.dirty) {
                    this.control.control.markAsPristine();
                }
            });
        }
    }
    

    你可以在你的代码中这样使用它:

    <input ignoreDirty type="text" name="my-name" [(ngModel)]="myData">
    

    【讨论】:

      【解决方案2】:

      您传播了您的更改,这就是它被标记为脏的原因。只需调整您的 writeValue 函数以不传播更改,因为从逻辑上讲它不应该创建更改:

      export class CustomInputComponent implements ControlValueAccessor {
          @Input("value") _value  = "";
          get value() {
              return this._value;
          }
          set value(val: string) {
              this._value = val;
              this.propagateChange(val);
          }
          @Input() noLabel: boolean = false;
          @Input() label: string = "Label required";
      
          propagateChange = (_: any) => {};
      
          writeValue(value) {
              if (value !== undefined) {
                  this._value = value;
              }
          }
          registerOnChange(fn) {
              this.propagateChange = fn;
          }
          registerOnTouched(fn) {}
      
      }
      

      简短地说:在您的writeValue 中使用this._value 而不是this.value

      【讨论】:

      • 是的!谢谢你..我想我只是需要另一双眼睛。谢谢。
      • @Bohms27 你应该已经可以了,你甚至有足够的积分来投票
      猜你喜欢
      • 2011-02-10
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 2018-06-21
      • 2011-01-04
      相关资源
      最近更新 更多