Vraag AngularJS - reset van $ scope.value verandert de waarde in template niet (willekeurig gedrag) [gesloten]


Bekijk het voorbeeld op http://jsfiddle.net/2NJ7y/3/ (versie van AngularJS 1.0.1). Er is een eenvoudige app die wacht op het invoeren van het geluksnummer. Als het aantal gelijk is aan 7, reset ik het geluksnummer naar nul. Als ik nummer 7 meerdere keren intyper, blijft het geluksgetal willekeurig of willekeurig in het invoerveld. Waarom? Hoe lost dit gedrag op? Bedankt.


11
2017-08-29 11:31


oorsprong


antwoorden:


Ik heb wat foutopsporing gedaan.

In de eerste plaats voor mij geluksgetal verblijf in het invoerveld niet willekeurig.

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 blijf in het invoerveld alleen als de vorige modelwaarde nul was.

Wat gebeurt er: wanneer u een 7-fired input-event invoert dat wordt afgehandeld luisteraar functie van invoerrichtlijn. Luisterfunctie-oproepen $ setViewValue. $ setViewValue stelt $ viewValue, $ modelValue, modelwaarde en calls $ viewChangeListeners in (ngChangeDirective voegt eenvoudig handler toe naar $ viewChangeListeners). Alarm wordt weergegeven, geluksnummer staat op nul. Toch als luckynumber van vorige waarde op vorige vuile controle verschilt $ watch handler en $ maken worden genoemd.

In mijn voorbeelden riep $ render op als de vorige modelwaarde "3" of "" was. Als de vorige modelwaarde null was, wordt $ render niet aangeroepen.

Waarom $ time-out met 0 vertraging werkt: wanneer u $ timeout belt met 0 vertragingsfunctie, wordt het wijzigen van luckynumber naar null uitgesteld aan het einde van evenementen wachtrij (alle javascript in een browser wordt op één thread uitgevoerd). $ viewChangeListener is geen wijzigingsmodelwaarde van 7 tot null. $ digest is voltooid. Dan wordt de $ timeout handler gebeld. Modelwaarde is ingesteld op nul. $ watch handler en $ render worden genoemd. $ render stelt de invoerwaarde in op "".


6
2017-09-08 14:02



Eindelijk een oplossing. Gebruik $ watch in plaats van ng-change:

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

Viool.

Deze andere ZO antwoord door @Valentyn deed me denken aan het proberen van die oplossing voor deze vraag.


2
2018-01-20 00:53



Als je simpelweg zet

$scope.luckynumber = undefined;

voorafgaand aan de waarschuwing elimineer je de race-conditie niet, maar je verandert het wel, zodat 7 wel correct wordt gewist, maar soms krijg je de waarschuwing twee keer.

Als de waarschuwingscode wordt vervangen door iets idempotent, zoals het wijzigen van de DOM om een ​​fout weer te geven, is dit probleem niet belangrijk.


1
2017-09-07 16:38