2016-04-19 3 views
0

Zuerst tut mir leid, wenn der Beitrag zu lang ist. Für den Fall, dass dies die Antworten, die Sie mir geben, irgendwie stört, definiere ich meinen Controller nicht auf die übliche Weise. Stattdessen folgen ich http://www.technofattie.com/2014/03/21/five-guidelines-for-avoiding-scope-soup-in-angular.html, und zu tun:

var game_1 = function($scope){ 
    var _this = this; 
    //some code 
    $scope.someFunction = function() { 
    _this.someFunction() ; 
    } ; 
} ; 
game1.prototype.someFunction = function() { 
    //some code 
} ; 
game_1.$inject = ['$scope'] ; 
app.controller('game_1', game_1) ; 

In meinem HTML, ich habe ein Objekt mit dem Attribut ng-show="checkRare". Nun, ich habe eine Reihe von Funktionen, die wie eine Art von Matrjoschka-Puppe arbeiten:

in der Steuerung definiert:

this.promptElement = function(message) { 
    var input = prompt(message) ; 
    if (input === null) { 
     this.resetCell(this.cellIJ) ; 
     return false ; 
    } else if (input === '') { 
     this.resetCell(this.cellIJ) ; 
     return '' ; 
    } else { 
     return input.toUpperCase() ; 
    } 
} ; 
//some more code 
$scope.function1 = function(i,j,F) { 
    _this.function1(i,j,F) ; 
} ; 
$scope.function2A = function(j) { 
    _this.function2A(j) ; 
} ; 
$scope.function2B = function(i,F) { 
    _this.function2B(i,F) ; 
} ; 
$scope.function3A = function() { 
    _this.function3A() ; 
} ; 
$scope.function3B = function() { 
    _this.function3B() ; 
} ; 
$scope.function4 = function() { 
    $scope.checkRare = true ; //THE PROBLEM LIES HERE 
    _this.function4() ; 
} ; 

Und draußen, ich habe:

game_1.prototype.function1 = function(i,j,F) { 
    //some code 
    this.inputElement = this.promptElement('Enter element name') ; 
    //some more code 
} ; 
game_1.prototype.function2A = function(j) { 
    //some code 
    for (var i = 1 ; i < 8 ; i++) { 
     this.function1(i,j) ; 
     if (this.inputElement === false) { return ; } 
    } 
} ; 
game_1.prototype.function2B = function(i,F) { 
    //some code 
    for (var j = j0 ; j < jF ; j++) { 
     this.function1(i,j,F) ; 
     if (this.inputElement === false) { return ; } 
    } 
} ; 
game_1.prototype.function3A = function() { 
    //some code 
    for (var j = 1 ; j < 19 ; j ++) { 
     this.function2A(j) ; 
     if (this.inputElement === false) { return ; } 
    } 
} ; 
game_1.prototype.function3B = function() { 
    //some code 
    for (var i = 6 ; i < 8 ; i++) { 
     this.function2B(i,true) ; 
     if (this.inputElement === false) { return ; } 
    } 
} ; 
game_1.prototype.function4 = function() { 
    //some code 
    this.function3A() ; 
    if (this.inputElement === false) { return ; } 
    this.function3B() ; 
} ; 

jedoch als jemand in einer anderen Frage vorgeschlagen, die ich fragte, wird die $scope wird nicht aktualisiert, bis die gesamte Funktion beendet ist, so dass ich nicht in der Lage, die Auswirkungen von $scope.checkRare = true bis zum Ende zu sehen. Damit es das erste ist, was passiert, habe ich versucht, $scope.$apply zu verwenden, aber ich bekomme den Fehler $apply already in progress (den ich übrigens auch manchmal zufällig bekomme). Ich habe auch versucht, $timeout und eine 'safeApply' Ansatz (https://coderwall.com/p/ngisma/safe-apply-in-angular-js) zu verwenden, aber keiner arbeitete.

Also, irgendwelche Ideen, wie man das Ergebnis von $scope.checkRare = true vor dem Rest der Funktion zu sehen, läuft seinen Kurs? Und, als eine sekundäre Frage, könnte mir jemand sagen, warum ich manchmal die $apply already in progress bekomme, auch wenn ich nicht ausdrücklich $scope.$apply verwende?

Vielen Dank im Voraus! Und nochmal, Entschuldigung für den langen Post! :)

+0

Ich bin mir nicht sicher, ob ich Ihre Frage zu $ ​​ad apply ohne ein funktionierendes Beispiel genau beantworten kann. Es gibt eine Reihe von Faktoren, die den von Ihnen erwähnten Fehler auslösen können. – Trevor

+0

Hier habe ich eine Geige gemacht (hoffe ich habe es richtig gemacht): https://jsfiddle.net/MarioMG/7zeae1eu/3/ Noch ein paar Bugs, um die ich mich kümmern muss, aber das ist es im Grunde genommen. –

+0

Ich konnte den Fehler nicht reproduzieren. Haben Sie Schritte, um es auszulösen? – Trevor

Antwort

1

ich vielleicht nicht ganz verstehe Ihre Frage, aber ich denke, was Sie suchen so etwas wie dieses:

... 
$scope.doSomething = function(){ 
    $scope.checkRare = true; 
    $timeout(function(){ 
    // check for results of setting $scope.checkRare 
    }); 
} 
... 

Um zu verstehen, warum dies funktioniert, hilft es, die JavaScript Event Loop zu verstehen. Kurz gesagt, das DOM wird erst am Ende einer Event-Loop-Iteration aktualisiert. Jede Iteration durch die Schleife endet erst, wenn der JavaScript-Engine der Code zur Ausführung ausgegangen ist. Wenn Sie Code in einen Timeout-Callback (ohne Verzögerung) einfügen, geben Sie der JavaScript-Engine im Wesentlichen vor, diesen Callback in der nächsten Iteration der Schleife auszuführen (so dass das DOM aktualisiert werden kann, bevor der Callback ausgeführt wird).

+0

Das wars! Vielen Dank! Ich hatte es falsch gemacht, ich dachte, ich müsste das '$ scope.checkRare = true'-Bit innerhalb des' $ timeout' anstelle des Rests der Funktion einpacken. Jetzt, wo ich es getan habe, wie du sagst, funktioniert alles! : D –

Verwandte Themen