• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

358
Views
Angular: establecer una cadena vacía en un valor predeterminado no actualiza correctamente el campo de texto enlazado si el campo tenía previamente el valor predeterminado

Estoy usando un método SET para establecer mi valor límite en 'DEFAULT' si alguna vez intentamos establecerlo en una cadena vacía. La entrada de texto enlazado se comporta correctamente en todos los escenarios, EXCEPTO si el campo de texto ya dice 'PREDETERMINADO' y yo "selecciono todo + elimino" ese valor. El valor límite se vuelve a establecer correctamente en 'DEFAULT' inmediatamente, pero el campo de entrada permanece vacío.

Los métodos get/set

la plantilla

Aquí hay un stackblitz que muestra el problema https://stackblitz.com/edit/angular-a9j8tv?file=src%2Fapp%2Fapp.component.html

Si tiene 'DEFAULT' y selecciona todo y elimina, puede ver que la entrada permanece vacía, pero el intervalo que está vinculado al mismo valor muestra correctamente el valor 'DEFAULT' recién restablecido.

¿Por qué pasó esto? ¿Hay un trabajo alrededor?

over 3 years ago · Santiago Trujillo
2 answers
Answer question

0

El problema proviene de ngModel . Que desde el '' valor manipulando a DEFAULT , que es el último valor que ha ngModel , ngModel no se da cuenta del cambio de valor para activar un nuevo evento de cambio de valor.

Cómo solucionarlo;

He asignado el valor cambiado directamente a la variable en el setter antes de la comparación. Luego, establezca un tiempo de espera mínimo para que ngModel pueda actualizar su valor existente. Luego, cuando comparo el nuevo valor y lo vuelvo a cambiar a DEFAULT en el caso de '' , ngModel se da cuenta del cambio de valor y activa el nuevo evento de cambio de valor. Esto actualiza ambas representaciones.

Encuentre stackblitz actualizado

over 3 years ago · Santiago Trujillo Report

0

error inherente

La directiva ngModel usa @Input y @Output para obtener el valor y emitir el evento de cambio. Por lo tanto, vincular una función como setter o getter a una directiva como [ngModel] con la estrategia de detección de cambios predeterminada activaría la función para cada detección de cambios.

Para replicar este error, conecte un console.log en el getter, escriba algún valor y siga presionando la tecla de retroceso en <input> y suéltelo. Podría ver que los mensajes de console.log se siguen imprimiendo.

Error de replicación: Stackblitz


¿Por qué no se inserta 'DEFAULT' en Ctrl + a + Retroceso ?

Como se dijo antes, la directiva ngModel usa @Input y, en consecuencia, el gancho ngOnChanges() para obtener cualquier cambio en el valor de la etiqueta <input> . Una cosa importante a tener en cuenta es que ngOnChanges() no se activará si el valor no ha cambiado (1) .

Podríamos intentar dividir el enlace bidireccional [(ngModel)] a la entrada [ngModel] y la salida (ngModelChange) .

 export class AppComponent { public testString: string; onChange(value: string) { this.testString = value === '' ? 'DEFAULT' : value; } }
 <input type="text" [ngModel]="testString" (ngModelChange)="onChange($event)" />

Todavía propenso a errores: Stackblitz

Aquí, Ctrl + a + Retroceso cualquier cadena que no sea 'DEFAULT' insertaría 'DEFAULT' como se esperaba. Pero Ctrl + a + Retroceso 'DEFAULT' daría como resultado un cuadro <input> vacío debido al ngOnChanges() discutido anteriormente.


Solución

Una forma de lograr el comportamiento esperado es no depender del ngModel ngOnChanges() de la directiva ngModel para establecer el valor, sino hacerlo nosotros mismos manualmente. Para eso, podríamos usar una variable de referencia de plantilla Angular en <input> y enviarla al componente para su posterior manipulación.

 export class AppComponent { public testString: string; public onChange(value: string, inputElem: HTMLInputElement) { this.testString = value === '' ? 'DEFAULT' : value; inputElem.value = this.testString; } }
 <input type="text" #myInput ngModel (ngModelChange)="onChange($event, myInput)" />

Ejemplo de trabajo: Stackblitz

Aquí #myInput es la variable de referencia de la plantilla. Si esto se siente extraño, debe saber que usar ngModel para manipular <input> se denomina en sí mismo formularios basados en plantillas . Y es bastante legal manipular la referencia de la plantilla directamente.

Dicho todo esto, en mi opinión, en los casos en que se necesite tal manipulación de entrada, le recomiendo que use los formularios reactivos angulares en su lugar. Proporciona un control más granular sobre la entrada.


(1) ngOnChanges() no se activará si el valor previousValue y el valor @Input del objeto SimpleChange de la variable currentValue respectiva no han cambiado.

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error