2016-06-02 7 views
1

Zuerst eine kurze Beschreibung dessen, was ich tun möchte: Ich möchte die Elemente eines Arrays durchlaufen und seinen Inhalt anzeigen. Basierend auf den Informationen, die ich von dem Element innerhalb des Arrays erhalten habe, möchte ich einen Knopf zeigen - oder nicht.ng - wenn es zu einer Endlosschleife führt

Aber das scheint nicht zu funktionieren. Schauen wir uns den Code einen Blick:

<div class="padding20" ui-view="create-event-form" ng-controller="detailedViewController" ng-init="loadDetails()"> 
<button type="submit" class="button success" ng-if="getParticipationStatus(eventDetails._id)">Participate on this event!</button> 

Wie Sie sehen, habe ich Zugriff innerhalb von ng-wenn eine Methode aus meiner detailedViewController. Die detailedViewController enthält die folgende Methode:

$scope.getParticipationStatus = function(eventId) { 
    var userName = cookieUserManagement.getUsername(); 
    userClient.getUserEvents(eventId, userName, function (success, hostingList) { 
     var i = 0; 
     var participationStatus; 
     if (success) { 
      hostingList = hostingList.ownEvents; 
      if (hostingList.length > 0) { 
       for (i = 0; i < hostingList.length; i++) { 
        if (hostingList[i]._id == eventId) { 
         participationStatus = true; 
        } else { 
         participationStatus = false; 
        } 
       } 
       return participationStatus; 
      } 
     } 
    }); 
}; 

Und jetzt das Problem: Alle Parameter in der richtigen Art und Weise behandelt werden. Ich sehe die richtigen IDs, richtige Objekte, alles scheint korrekt zu sein. Aber dieses Stück Code führt zu einer Endlos-Schleife (dh in einer Alarmbereitschaft versetzt und genießt nie Warnungen von Ihrem Browser endet) und die folgende Fehlermeldung:

angular.js:13642TypeError: callback is not a function 
at services.js:374 
at angular.js:16104 
at m.$eval (angular.js:17378) 
at m.$digest (angular.js:17191) 
at m.$apply (angular.js:17486) 
at l (angular.js:11637) 
at D (angular.js:11843) 
at XMLHttpRequest.w.onload (angular.js:11776)(anonymous function) @ angular.js:13642 


angular.js:13642Error: [$rootScope:infdig] http://errors.angularjs.org/1.5.6/$rootScope/infdig?p0=10&p1=%5B%5D 
at Error (native) 
at http://127.0.0.1:3000/node_modules/angular/angular.min.js:6:412 
at m.$digest (http://127.0.0.1:3000/node_modules/angular/angular.min.js:143:281) 
at m.$apply (http://127.0.0.1:3000/node_modules/angular/angular.min.js:145:401) 
at l (http://127.0.0.1:3000/node_modules/angular/angular.min.js:97:250) 
at D (http://127.0.0.1:3000/node_modules/angular/angular.min.js:101:373) 
at XMLHttpRequest.w.onload (http://127.0.0.1:3000/node_modules/angular/angular.min.js:102:397) 

Soweit ich sehe, ich habe erklärt, alles in einem richtiger Weg. Aber ich weiß nicht, warum das zu einer Endlosschleife führt.

Jede Hilfe wird geschätzt! Danke im Voraus.

+5

Ja, weil die Verwendung einer Funktion in 'ngIf' eine der schlimmsten Praktiken ist, die Sie haben können. Es wird es auf jeder Digest-Schleife immer wieder aufrufen. Sie müssen den Ausdruck an eine Eigenschaft binden, die das Ergebnis von 'getParticipationStatus()' (anstelle der Funktion selbst) darstellt. –

+1

Es sieht so aus, als ob Ihre Funktion 'getUserEvents' asynchron ist und Sie vom Rückruf zurückkommen. Kein Code wird tatsächlich den Wert von 'participationStatus' beobachten, Sie müssen ihn möglicherweise im Bereich' $ scope.participationStatus = participationStatus; 'speichern und diesen Wert in' ng-if = "participationStatus" 'verwenden. –

+0

Ja, Sie haben Recht . Das Stichwort "Asynchronität" führte mich zur endgültigen Lösung. Danke euch beiden! –

Antwort

2

Die Funktion in Ihrem ng-if ist asynchron, so dass der boolesche Wert nicht zurückgegeben wird, da angular es erwartet. Es könnte sogar den Wert überhaupt nicht zurückgeben, da der Rückruf nicht aufgerufen würde.

Ich empfehle, die beobachtete ng-if-Eigenschaft in eine Bereichsvariable anstelle eines Funktionsaufrufs zu ändern. Dann können Sie Ihre asynchrone Funktion wann immer Sie wollen aufrufen (durch setInterval oder was auch immer ... aber Sie sollten einen besseren Weg finden) und im Callback setzen Sie einfach die Scope-Variable auf wahr oder falsch. Ng-if "überwacht" den Wert der Variablen und löst einen Digest aus, in dem das Element gerendert wird oder nicht. So sollte es so etwas wie dies in der Ansicht aussehen:

<div class="padding20" ui-view="create-event-form" ng-controller="detailedViewController" ng-init="loadDetails()"> 
<button type="submit" class="button success" ng-if="participationStatus">Participate on this event!</button> 

Und die Controller-Methode:

$scope.getParticipationStatus = function(eventId) { 
    var userName = cookieUserManagement.getUsername(); 
    userClient.getUserEvents(eventId, userName, function (success, hostingList) { 
     var i = 0; 
     if (success) { 
      hostingList = hostingList.ownEvents; 
      if (hostingList.length > 0) { 
       for (i = 0; i < hostingList.length; i++) { 
        if (hostingList[i]._id == eventId) { 
         $scope.participationStatus = true; 
        } else { 
         $scope.participationStatus = false; 
        } 
       } 
      } 
     } 
    }); 
}; 

Das einzige, was bleibt, ist das Verfahren zum Beispiel bei der Steuerung intialization zu nennen, so dass nur $ scope .getParticipationStatus ($ scope.eventDetails._id) im Body der Controller-Funktion.

+0

Ich denke, Sie sollten die erforderlichen Änderungen in der Ansicht und der Controller enthalten, da es wie das OP nicht verstehen, wie Async-Anrufe funktionieren –

+1

Sie haben Recht. Ich habe versucht, so wenige Änderungen wie möglich zu machen. Vorausgesetzt, das sollte funktionieren. –

+0

Vielen Dank für Ihre großartige Arbeit. Ich habe es nicht genau so umgesetzt.In meinem HTML habe ich hinzugefügt, in der gleichen Weise wie Sie es taten: Und zu meinem Controller die folgende Zeile (n) hinzugefügt (für mehr Lesbarkeit habe ich nicht die Logik kopiert, um das Ergebnis zu erhalten TRUE oder FALSE): detailedObject.participateStatus = participationStatus ; Und rufen Sie die Methode, um diesen Wert auf mein JSON-Objekt mit ng Init setzen. Vielen Dank für Ihr gutes Beispiel! –

Verwandte Themen