property - ngmodel angular 6
Directiva de atributo con ngModel para cambiar el valor del campo (4)
Aunque la respuesta de Günter parece prometedora, hay un error en que el valor final en el modelo tiene la última letra ingresada en minúsculas.
Mira aquí:
https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH
Por favor use la respuesta provista en la pregunta. Funciona correctamente
@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)
}
}
Quiero cambiar (forzar) los valores de los campos de entrada mientras escribo con una directiva de atributo. Con él me gustaría crear directivas como mayúsculas, minúsculas, maxlength, filterchar, etc. para ser utilizadas en campos de entrada en formularios. Encontré este ejemplo: Ejemplo de directriz de atributo de Angular 2 Ejemplo, pero esto no parece funcionar. Tal vez lo hizo para una versión anterior de Angular2. Sin embargo, es exactamente lo que me gustaría hacer.
Cuando creo una directiva como esta:
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);
}
}
Y úsalo en un formulario como este:
<input type="text" class="form-control" [(ngModel)]="field.name" ngControl="name" #name="ngForm" required uppercase>
(y registrar a NgModel
como proveedor). Me sale un
undefined this.model.value
Puedo usar $event.target.value = $event.target.value.toUpperCase()
(cuando se pasa $event
con el onInputChange()
) y funciona para la vista (muestra la entrada como mayúscula. Pero no funciona t actualizar el campo de enlace "field.name".
Entonces, ¿cómo crear una directiva de atributo Angular2 que haga esto?
- EDITAR -
Después de un poco más de investigación conseguí lo que quería. La respuesta que proporcionó Günter está más cerca de mi intención original y quizás mejor. Pero aquí hay otra manera:
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)
}
}
Como dije, no estoy seguro si esta también es una buena forma de hacerlo, así que los comentarios son bienvenidos.
El requisito que tuve que crear una directiva para recortar los espacios iniciales y finales para la entrada de texto. mi solución:
import { Directive, ElementRef, HostListener, Output, EventEmitter } from ''@angular/core'';
import { NgModel } from "@angular/forms";
@Directive({
selector: ''[text-trim]'',
providers: [NgModel]
})
export class TextInputTrimDirective {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
constructor(private el: ElementRef) {}
@HostListener(''change'') onInputChange() {
const value = this.el.nativeElement.value.trim();
this.ngModelChange.emit(value);
}
}
He enfrentado el mismo problema, donde necesito crear la selección personalizada en Angular con select2 . He creado la siguiente cosa de la directiva para lograr esto con la directiva de atributo y 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());
}
});
}
}
con el siguiente uso
<select custom-select [(ngModel)]="protocol.type">
<option value="1">option1</option>
<option value="1">option2</option>
</select>
actualizar
Este enfoque no funciona correctamente. Vea la respuesta de @RanyanHow para una mejor solución.
original
@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());
}
}