私は、<data-input-text>
カスタムコンポーネントを持っています。このコンポーネントには、通常モードと無効モードの2つのモードがあります。ここでテンプレート(私はそれをデモケースのためのビットを簡素化しました)です:親フォームでテンプレート駆動型のカスタムControlValueAccessor
<label *ngIf="!disabled"
class="field-label"
[ngClass]="{'focused' : isFocused, 'with-errors' : errors}">
<input class="field-value"
[type]="type"
[required]="required"
(focus)="onFocus()"
(blur)="onBlur()"
[(ngModel)]="value"
#fieldInput="ngModel">
</label>
<div class="field-label" *ngIf="disabled">
<span class="field-value">{{ value }}</span>
<span class="field-name">{{ label }}</span>
</div>
、私は次のように、このコンポーネントを使用します。
<form #profileForm="ngForm">
<data-text-input
label="lastName"
[required]="true"
[disabled]="userIsRegistered"
name="lastName"
ngModel></data-text-input>
</form>
userIsRegistered
入力フィールドまたはコンポーネント内のスパンを切り替えるブール値を返します。それまではすべてここまでうまくいきます。
私はこのようなBehaviorSubjectに一致するように親コンポーネントに形式を設定します。ここでは
this._sub = this.dl.selectedEmployee.subscribe(u => {
if (u.id) {
this.isLoading = false;
setTimeout(() => {
this.profileForm.setValue(u);
this.profileForm.control.markAsPristine();
}, 10);
}
});
はカスタムControlValueAccessor コンポーネントです:
import { Component, Input, ViewChild, forwardRef,
AfterViewInit, OnInit, OnChanges,
NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS,
ControlValueAccessor, FormControl,
Validator, NgForm } from '@angular/forms';
@Component({
selector: 'data-text-input',
template: `
<label *ngIf="!disabled"
class="field-label">
<input class="field-value"
[type]="type"
[required]="required"
(blur)="onBlur()"
[(ngModel)]="value"
#fieldValue="ngModel">
<span class="field-name">{{ label }}</span>
</label>
<div class="field-label" *ngIf="disabled">
<span class="field-value">{{ value }}</span>
<span class="field-name">{{ label }}</span>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(()=> DataTextInputComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(()=> DataTextInputComponent),
multi: true
}
]
})
export class DataTextInputComponent implements OnChanges, ControlValueAccessor, Validator {
@Input() public disabled: boolean = false;
@Input() public label: string;
@Input() public required: boolean = false;
@Input() public type: string = 'text';
@ViewChild('fieldValue') public fieldValue: FormControl;
// infrastructure
public registerOnChange(fn: any) { this.propagateChange = fn; }
public registerOnTouched(fn: any) { this.propagateTouch = fn; }
private propagateChange = (_: any) => { };
private propagateTouch = (_: any) => { };
/**
* inner value
*/
private innerValue: any = null;
/**
* on changes hook
*/
public ngOnChanges(): void {
if (this.disabled) {
this.propagateChange(this.innerValue);
}
}
/**
* input events
*/
public onBlur(): void {
this.propagateChange(this.innerValue);
this.propagateTouch(true);
}
/**
* value accessor setter and getter
*/
public get value(): any {
return this.innerValue;
};
public set value(value: any) {
if (value !== 'undefined') {
this.innerValue = value;
this.propagateChange(value);
this.propagateTouch(true);
}
}
/**
* value accessor implementation
* @param value
*/
public writeValue(value: any): void {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
/**
* validation
* @param c
*/
public validate(c: FormControl) {
return this.errors = (this.disabled) ? null : this.customValidate(c);
}
private customValidate(c: FormControl): {} {
if (c.touched) {
// some validation logic which is not relevant here;
return null;
}
return null;
}
}
に使用される他のコンポーネントがあります。フォームも同じです(カラーピッカーとng-selectのように)。
これは奇妙な部分です。フォームの値は正しく設定されています。エラーはありません。値は、データ・テキスト入力コンポーネント内の正しく表示されます(disabled
と!disabled
の両方)、およびフォーム内の他のコンポーネント)。変わった部分は、this.profileForm
オブジェクトをデバッガで検査すると、controls
プロパティにはそれぞれの値を持つすべてのコントロールがありますが、disabled
プロパティ(別名入力フィールドなし)が設定されているフォームのvalue
プロパティはそれらを逃しています本当。ここで
はPlunkerは次のとおりです。https://plnkr.co/edit/nbWQZzQjhGae622CanGa?p=preview
任意のアイデア?
あなたのコードに電子メールコントロールが表示されません。あなたの問題を示すプランナーを作成できますか? – yurzui
私は質問をplunker – pop
に更新しました[コードやエラーの画像を投稿しない](https://meta.stackoverflow.com/q/303812/995714)また、ここでの問題ではなく、将来的に誰も助けない明日に変化したり消えたりすることができるプランナーではありません:[mcve] – Rob