Directive d'attribut avec ngModel pour changer la valeur du champ
je veux modifier (forcer) les valeurs des champs d'entrée en tapant à l'aide d'une directive d'attribut. Avec cela je voudrais créer des directives comme uppercase, lowercase, maxlength, filterchar, etc. à utiliser dans les champs d'entrée des formulaires. J'ai trouvé ça par exemple: Angular 2 Attribut Directive Typescript Example mais cela ne semble pas fonctionner. Peut-être pour une construction antérieure D'Angular2. Il est cependant exactement ce que je voudrais faire.
Quand je crée une directive comme ceci:
import {Directive} from 'angular2/core';
import {NgModel} from 'angular2/common';
@Directive({
selector: '[ngModel][uppercase]',
host: {
'(input)' : 'onInputChange()'
}
})
export class UppercaseDirective{
constructor(public model:NgModel){}
onInputChange(){
var newValue = this.model.value.toUpperCase();
this.model.valueAccessor.writeValue(newValue);
this.model.viewToModelUpdate(newValue);
}
}
Et l'utiliser dans un formulaire comme ceci:
<input type="text" class="form-control" [(ngModel)]="field.name" ngControl="name" #name="ngForm" required uppercase>
(et vous inscrire NgModel
en tant que fournisseur). Je reçois un
undefined.modèle.valeur.
je peux utiliser $event.target.value = $event.target.value.toUpperCase()
(lors du passage d' $event
onInputChange()
) et cela fonctionne pour la vue (cela montre l'entrée en majuscules. Mais il ne met pas à jour le champ "bind field".nom".
alors comment créer une directive d'attribut Angular2 qui ne cette?
-- EDIT --
Après quelques recherches, j'ai réussi à obtenir ce que je veux. La réponse fournie par Günter est plus proche de mon intention initiale et peut-être meilleure. Mais voici une autre façon:
import {Directive, Input, Output, EventEmitter} from 'angular2/core';
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
comme je l'ai dit, Je ne suis pas sûr que ce soit aussi une bonne façon de le faire, donc les commentaires sont les bienvenus.
3 réponses
mise à jour
Cette approche ne fonctionne pas correctement. Voir la réponse de @RyanHow pour une meilleure solution.
origine
@Directive({
selector: '[ngModel][uppercase]',
providers: [NgModel],
host: {
'(ngModelChange)' : 'onInputChange($event)'
}
})
export class UppercaseDirective{
constructor(private model:NgModel){}
onInputChange(event){
this.model.valueAccessor.writeValue(event.toUpperCase());
}
}
bien que la réponse de Günter semble prometteuse, il y a un bug dans le fait que la valeur finale dans le modèle a la dernière lettre entrée en minuscules.
Voir ici:
https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH
veuillez utiliser la réponse fournie dans la question. Il fonctionne correctement.
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
J'ai fait face au même problème, où je dois créer le Select personnalisé en angle avec select2. J'ai créé la chose directive suivante pour réaliser ceci avec la directive attribut et ngModel
.
import {ElementRef, Directive, EventEmitter, Output, Input} from '@angular/core';
import {NgModel} from "@angular/forms";
declare let $;
@Directive({
selector: '[custom-select]',
providers: [NgModel]
})
export class CustomSelectComponent{
$eventSelect:any;
@Output() ngModelChange:EventEmitter<any> = new EventEmitter();
@Input() set ngModel(value:any){
//listen to the input value change of ngModel and change in the plugin accordingly.
if(this.$eventSelect){
this.$eventSelect.val(value).trigger('change',{fromComponent:true});
}
}
constructor(private elementRef: ElementRef) {}
ngOnInit(){
this.$eventSelect = $(this.elementRef.nativeElement);
this.$eventSelect.select2({minimumResultsForSearch:-1});
this.$eventSelect.on("change.select2", (event,data)=> {
//listen to the select change event and chanage the model value
if(!data || !data.fromComponent){ //dont change model when its chagned from the input change event
this.ngModelChange.emit(this.$eventSelect.val());
}
});
}
}
de l'utilisation suivante
<select custom-select [(ngModel)]="protocol.type">
<option value="1">option1</option>
<option value="1">option2</option>
</select>