Mit einem einfachen Eingabeelement kann ich dies tun:
<input [(ngModel)]="name" /> {{ name }}
Dies funktioniert nicht für meine benutzerdefinierten Elemente:
<my-selfmade-combobox [(ngModel)]="name" values="getValues()" required></my-selfmade-combobox>
Wie kann ich das umsetzen?
Ich denke, dieser Link beantwortet Ihre Frage:
Wir müssen zwei Dinge implementieren, um das zu erreichen:
ControlValueAccessor
, das die Brücke zwischen dieser Komponente und ngModel
/ngControl
implementiert.Der vorherige Link gibt Ihnen ein vollständiges Beispiel ...
Ich habe das ngModel einmal für die Eingabe in meine gemeinsam genutzten Komponenten implementiert und kann es dann sehr einfach erweitern.
Nur zwei Codezeilen:
anbieter: [createCustomInputControlValueAccessor (MyInputComponent)]
erweitert InputComponent
my-input.component.ts
import { Component, Input } from '@angular/core';
import { InputComponent, createCustomInputControlValueAccessor } from '../../../shared/components/input.component';
@Component({
selector: 'my-input',
templateUrl: './my-input-component.component.html',
styleUrls: ['./my-input-component.scss'],
providers: [createCustomInputControlValueAccessor(MyInputComponent)]
})
export class MyInputComponent extends InputComponent {
@Input() model: string;
}
my-input.component.html
<div class="my-input">
<input [(ngModel)]="model">
</div>
input.component.ts
import { Component, forwardRef, ViewChild, ElementRef, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
export function createCustomInputControlValueAccessor(extendedInputComponent: any) {
return {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => extendedInputComponent),
multi: true
};
}
@Component({
template: ''
})
export class InputComponent implements ControlValueAccessor, OnInit {
@ViewChild('input') inputRef: ElementRef;
// The internal data model
public innerValue: any = '';
// Placeholders for the callbacks which are later provided
// by the Control Value Accessor
private onChangeCallback: any;
// implements ControlValueAccessor interface
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
// implements ControlValueAccessor interface
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
// implements ControlValueAccessor interface - not used, used for touch input
registerOnTouched() { }
// change events from the textarea
private onChange() {
const input = <HTMLInputElement>this.inputRef.nativeElement;
// get value from text area
const newValue = input.value;
// update the form
this.onChangeCallback(newValue);
}
ngOnInit() {
const inputElement = <HTMLInputElement>this.inputRef.nativeElement;
inputElement.onchange = () => this.onChange();
inputElement.onkeyup = () => this.onChange();
}
}