2017-09-22 13 views
1

私は、入力をHTMLでラップし、ラベルなどを追加するテンプレート駆動型フォームを使ってカスタムフォームコントロールを実装しました。これは、ngModelの2wayデータバインディングでフォームとちょうどうまく会話します。問題は、初期化時にフォームが自動的にダーティとマークされることです。これが起こらないようにする方法はありますか?フォーム上でこれらのプロパティを使用することができ、正確になりますか?Angular4ダーティチェックからプロパティを除外する

カスタムセレクタ(これは自動的にダーティとマークされているよりも細かい他の作品):

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

 
}

答えて

2

あなたはそれがダーティとマークされている理由である、あなたの変更を伝播します。まもなく

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機能を適応させるあなたのwriteValue

+1

はい!ありがとうございました..私はちょうどそれの目の別のセットが必要だったと思います。ありがとうございました。 – Bohms27

+0

私はできればマークします! – Bohms27

+0

@ Bohms27あなたはすでにできるはずです、あなたはupvoteのための十分なポイントがあります – smnbbrv

0

this._valueを使用する代わりにthis.value私は解決しているだけの属性ディレクティブで:

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"> 
関連する問題