Wenn Sie eine benutzerdefinierte Komponente für die Datenbindung an einen einzelnen Wert implementieren möchten Die richtige Winkelmethode hierfür ist die Vorgehensweise, bei der die übergeordnete Ansicht entweder [formControl]
oder [formControlName]
angibt.
<app-form-group formControlName="name"></app-form-group>
<app-form-group formControlName="email"></app-form-group>
<app-form-group formControlName="other"></app-form-group>
In Ihrem Kind Kontrolle müssen Sie Folgendes tun:
Zuerst fügen Sie den folgenden Anbieter auf Ihre @Component
Erklärung, so Angular Ihre Komponente kennt [formControlName]
/[formControl]
arbeiten kann
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CountrySelectorComponent),
multi: true
}
]
Die Klasse Ihrer untergeordneten Komponente muss dann die Schnittstelle ControlValueAccessor
implementieren. Diese sollte ein voll funktionierendes Beispiel sein, wenn nicht dann lassen Sie mich wissen, und ich werde den Code ändern, tippte ich es direkt in den Browser.
@Component({
// Ensure [formControl] or [formControlName] is also specified
selector: '[formControl] app-form-group, [formControlName] app-form-group',
templateUrl: './country-selector.component.html',
styleUrls: ['./country-selector.component.scss'],
providers: [
{
// Provide the value accessor
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CountrySelectorComponent),
multi: true
}
]
})
export class CountrySelectorComponent implements ControlValueAccessor {
private value: any;
private hasHadFocus = false;
private hasNotifiedTouched = false;
private propagateChange: any =() => {};
private propogateTouched: any =() => {};
public changed(event: any) {
this.value = event.srcElement.value;
this.propagateChange(this.value);
}
/**
* Called when (focus) is triggered
*/
public focused() {
this.hasHadFocus = true;
}
/**
* Called when (blur) is triggered
*/
public blurred() {
if (this.hasHadFocus && !this.hasNotifiedTouched) {
// Only notify once, and only if lost focus after a focus
this.hasNotifiedTouched = true;
this.propogateTouched();
}
}
/**
* Called when a new value is set via code
* @param obj
*/
writeValue(obj: any): void {
this.value = obj;
}
/**
* Register a call back to call when our value changes
* @param fn
*/
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
/**
* Register a call back to call when our value is first touched
* @param fn
*/
registerOnTouched(fn: any): void {
this.propogateTouched = fn;
}
}
Ihre app-form-group
Vorlage wäre so etwas wie dieses
<div class="form-group">
<label class="col-md-2 control-label">{{Name}}</label>
<div class="col-md-9">
<input class="form-control" (blur)="blurred()" focus="focussed()" change="changed($event)">
</div>
- hinzufügen
[formGroup]="signupForm"
jedem Ihrer app-form-group
Instanzen in der Hauptansicht sehen
- OnInit Implementieren in Ihrer
app-form-group
Kontrolle.
- hinzufügen
private controlContainer: ControlContainer
an den Konstruktor Ihrer app-form-group
Komponente so Angular es
- hinzufügen
public form: FormGroup;
Eigenschaft auf Ihre app-form-group
Komponente injizieren.
In ngOnInit fügen Sie den folgenden Code
this.form = this.containerControl.control;
In Ihrer app-form-group
Vorlage würden Sie hinzufügen [formGroup] wie so
Mit dieser Methode ist, dass die geringste Menge an Code erfordert, und ist das, was ich empfehlen würde, wenn Sie einbetten möchten Composite-Steuerelemente, die mehrere Datenelemente bearbeiten (wie eine Adresse).
Von diesem Blog ->https://mrpmorris.blogspot.co.uk/2017/08/angular-composite-controls-formgroup-formgroupname-reactiveforms.html
Sie benötigen, um Ihre eigene 'ControlValueAccessor' zu implementieren, wie hier geführt http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls- in-angular-2.html –