2016-07-30 14 views
1

Ich versuche etwas zu tun, das ziemlich einfach sein sollte - Laden Sie ein Objekt aus meiner Firebase DB und weisen Sie es einer Variablen in meinem Controller zu. Das funktionierte perfekt vorher, als ich Firebase-Funktionen verwendete (siehe auskommentierten Code), aber ich möchte 3-Wege-Bindung verwenden, also versuche ich dasselbe in AngularFire zu machen.

Das $ loaded -Ereignis scheint nicht zu feuern, da das Planer-Objekt (noch das "Sie sind hier") niemals auf die Konsole gedruckt wird. Die Zeichenfolge user.uid wird wie erwartet an die Konsole ausgegeben, und der auskommentierte Code funktioniert einwandfrei. Vielen Dank im Voraus für Ihre Hilfe.

(Side Frage: Im Code auf Kommentar, ich mache Gebrauch von evalAsync die Formulare auf der Webseite, um sicherzustellen, tatsächlich aktualisieren, wenn die Informationen abgerufen werden - ist dies eine gute Praxis?)

Mein Controller:

firebase.auth().onAuthStateChanged(function(user) { 
     if (user) { 
      console.log("Currently logged in user..."); 
      console.log(user.uid); 
      $scope.user = user; 

      var ref = firebase.database().ref('planners/' + $scope.user.uid); 
      var planner = $firebaseObject(ref); 

      planner.$loaded().then(function() { 
       console.log("You are here") 
       console.log(planner) 
      }) 
      .catch(function(error) { 
       console.log(error) 
      }) 
      // firebase.database().ref('planners/' + $scope.user.uid).on('value', function(response) { 
      // if (response.val() != null) { 
      //  $scope.$evalAsync(function() { 
      //   $scope.planner = response.val(); 
      //  }) 
      // } 
      // }); 
     } 
     else { 
      console.log('No user logged in') 
      $state.go('login') 
     } 
    }) 

Antwort

0

Wie @Aaron Saunders vorgeschlagen, sollten Sie die AngularFire Auth Objekt verwenden, da es besser integriert mit kantigem (Updates $scope s, Trigger $digest s etc.) ist.

Der Code, den Sie vorher hatten, arbeitete wegen der $evalAsync, die eine $digest feuert, wenn man nicht läuft (die $digest Schleife ist der Magier, der die Daten zwischen dem Modell und der Ansicht bindet).

Eigentlich sollten Sie AngularFire verwenden, um Daten zu binden. Sie bieten auch "3-Wege-Bindung" (Model-View-Datenbank) unter Verwendung von $bindTo.

Wie Sie in den $firebaseObjectdocs die Daten sehen können, werden vom Server zum Client synchronisieren automatisch, aber wenn Sie lokale Änderungen zurück an den Server speichern möchten, sollten Sie $save oder $bindTo verwenden.

-Code fix Vorschlag:

$firebaseAuth().$onAuthStateChanged(function(user) { 
    // By using `$firebaseAuth` this function will be called in a `$digest` so all changes will be bound 
    if (user) { 
     console.log("Currently logged in user..."); 
     console.log(user.uid); 
     $scope.user = user; 

     var ref = firebase.database().ref('planners/' + $scope.user.uid); 
     // `$destroy` previous bindings 
     if ($scope.planner && angular.isFunction($scope.planner.$destroy)) { 
      $scope.planner.$destroy(); 
     } 
     $scope.planner = $firebaseObject(ref); 

     // planner.$loaded().then(function() { 
     // // This code will happen only after `$digest` since its promise is relied on the `$q` service 
     // console.log("You are here") 
     // console.log(planner) 
     // }) 
     // .catch(function(error) { 
     // console.log(error) 
     // }) 
     // firebase.database().ref('planners/' + $scope.user.uid).on('value', function(response) { 
     // if (response.val() != null) { 
     //  $scope.$evalAsync(function() { 
     //   $scope.planner = response.val(); 
     //  }) 
     // } 
     // }); 
    } else { 
     console.log('No user logged in'); 
     $scope.user = null; 
     if ($scope.planner && angular.isFunction($scope.planner.$destroy)) { 
      $scope.planner.$destroy(); 
     } 
     $state.go('login'); 
    } 
});