Comment puis-je implémenter ngModel sur des éléments personnalisés? (propre zone de liste déroulante)
avec un élément d'entrée simple, je peux faire ceci:
<input [(ngModel)]="name" /> {{ name }}
cela ne fonctionne pas pour mes éléments personnalisés:
<my-selfmade-combobox [(ngModel)]="name" values="getValues()" required></my-selfmade-combobox>
Comment puis-je l'implémenter?
37
demandé sur
maklemenz
2016-02-02 12:30:38
2 réponses
je pense que ce lien répondra à votre question:
nous devons mettre en œuvre deux choses pour y parvenir:
- Un composant qui fournit la logique de votre composant formulaire. Il n'a pas besoin d'entrée puisque cela sera fourni par ngModel lui-même
- personnalisé
ControlValueAccessor
qui permettra de mettre en œuvre le pont entre cette composante etngModel
/ngControl
151990920"
le lien précédent vous donne un échantillon complet...
27
répondu
Thierry Templier
2018-03-15 13:47:11
j'ai implémenté le ngModel une seule fois pour l'entrée dans Mes composants partagés et à partir de là je peux l'étendre très simplement.
seulement deux lignes de code:
fournisseurs: [createCustomInputControlValueAccessor (MyInputComponent)]
s'étend dans le composant
mon entrée.composant.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;
}
mon entrée.composant.html
<div class="my-input">
<input [(ngModel)]="model">
</div>
"151930920 d'entrée".composant.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();
}
}
0
répondu
שלומי אהרוני
2018-07-19 10:56:44