2012-08-29 13 views
11

Eche un vistazo al ejemplo en http://jsfiddle.net/2NJ7y/3/ (versión de AngularJS 1.0.1). Hay una aplicación simple, que está esperando la entrada del número de la suerte. Si el número es igual a 7, restablezco el número de la suerte a nulo. Si ingreso el número 7 varias veces, en algún momento/al azar, el número de la suerte permanece en el campo de entrada. ¿Por qué? ¿Cómo se resuelve este comportamiento? Gracias.

+0

Esta es una buena pregunta. Estás entrando en una especie de condición de carrera aquí, que es la razón por la cual no se está resolviendo correctamente.Estaría interesado en encontrar una forma adecuada de resolver esto. – ganaraj

+1

¿Qué hay de usar [$ timeout service] (http://docs.angularjs.org/api/ng.$timeout)? http://jsfiddle.net/2NJ7y/10/ Pero nunca he entendido por qué funciona con 0 de retraso. –

+0

@Artem: No es una solución tan agradable, pero funciona. Pero todavía estoy esperando la solución definitiva. :-) Gracias. – user1595465

Respuesta

1

Si sólo tiene que poner

$scope.luckynumber = undefined; 

antes de la alerta que no eliminan la condición de carrera, pero lo cambia de manera que 7 no ser anulado correctamente, pero a veces se obtiene la alerta dos veces.

Si el código de alerta se reemplaza por algo idempotente, como alterar el DOM para mostrar un error, entonces este problema no será importante.

6

He hecho algunas depuraciones.

En primer lugar para mí, el número de la suerte permanece en el campo de entrada no al azar.

enter 3 (model==3, input==3) =>enter 7 (alert, model==null, input="")

=>enter 3 (model==3, input==3) =>remove 3 (model=="", input=="")

=>enter 7 (alert, model==null, input="")

=>enter 7 (alert, model==null, input="7")

7 estancia en campo de entrada sólo si anterior valor modelo era nulo.

¿Qué ocurre: cuando la entrada 7 despedido evento de entrada que es manejado por listener function de input directive. La función de escucha llama al $setViewValue. $ setViewValue establece $ viewValue, $ modelValue, model value y llama a $ viewChangeListeners (ngChangeDirective simply adds handler a $ viewChangeListeners). Se muestra Alert, LuckyNumber se establece en null. Después de todo, si el número de la suerte difiere del valor anterior en la verificación sucia anterior, se llaman $watch handler y $render.

En mi ejemplo $ renderizado llamado si el valor del modelo anterior era "3" o "". Si el valor del modelo anterior era nulo $ render no se llama.

qué tiempo muerto con $ 0 retardo funciona: cuando se llama tiempo de espera con la función $ 0 retardo con el cambio de luckynumber a nula se pospone al final de events queue (todo el JavaScript en un navegador ejecuta en un único subproceso). $ viewChangeListener no cambia el valor del modelo de 7 a nulo. $ digest finaliza. Luego se llama $ timeout handler. El valor del modelo se establece en nulo. $ watch handler y $ render son llamados. $ render establece el valor de entrada en "".

2

Por fin, una solución. Utilice $ en lugar de ver ng de cambio:

$scope.$watch('luckynumber', function() { 
    if ($scope.luckynumber == 7) { 
     alert('The lucky number mustn\'t be equal 7.'); 
     $scope.luckynumber = null; 
    } 
}) 

Fiddle.

Este otro SO answer de @Valentyn me hizo pensar en probar esa solución a esta pregunta.

Cuestiones relacionadas