javascript - Wie kann ich ein gelöstes Versprechen von einem AngularJS-Service mit $ q zurückgeben?



promise angular-promise (7)

Mein Service ist:

myApp.service('userService', [
  '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
    var deferred;
    deferred = $q.defer();
    this.initialized = deferred.promise;
    this.user = {
      access: false
    };
    this.isAuthenticated = function() {
      this.user = {
        first_name: 'First',
        last_name: 'Last',
        email: '[email protected]',
        access: 'institution'
      };
      return deferred.resolve();
    };
  }
]);

Ich rufe das in meiner config über:

myApp.run([
  '$rootScope', 'userService', function($rootScope, userService) {
    return userService.isAuthenticated().then(function(response) {
      if (response.data.user) {
        return $rootScope.$broadcast('login', response.data);
      } else {
        return userService.logout();
      }
    });
  }
]);

Es klagt jedoch, dass es then keine Funktion ist. Bekomme ich das gelöste Versprechen nicht zurück?


Answers

Für kürzeren JavaScript-Code verwenden Sie diesen:

myApp.service('userService', [
  '$q', function($q) {
    this.initialized = $q.when();
    this.user = {
      access: false
    };
    this.isAuthenticated = function() {
      this.user = {
        first_name: 'First',
        last_name: 'Last',
        email: '[email protected]',
        access: 'institution'
      };
      return this.initialized;
    };
  }
]);

Sie wissen, dass Sie die Bindung an userService.user verlieren, indem Sie sie mit einem neuen Objekt überschreiben, anstatt nur die Objekteigenschaften festzulegen.

Ich meine hier ein Beispiel für meinen plnkr.co-Beispielcode (Arbeitsbeispiel: http://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview ):

angular.module('myApp', []).service('userService', [
    '$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) {
    this.initialized = $q.when(null);
    this.user = {
        access: false
    };
    this.isAuthenticated = function () {
        this.user.first_name = 'First';
        this.user.last_name = 'Last';
        this.user.email = '[email protected]';
        this.user.access = 'institution';
        return this.initialized;
    };
}]);

angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
    $scope.user = userService.user;
    $scope.callUserService = function () {
        userService.isAuthenticated().then(function () {
            $scope.thencalled = true;
        });
    };
}]);

Versuche dies:

myApp.service('userService', [
    '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
      var deferred= $q.defer();
      this.user = {
        access: false
      };
      try
      {
      this.isAuthenticated = function() {
        this.user = {
          first_name: 'First',
          last_name: 'Last',
          email: '[email protected]',
          access: 'institution'
        };
        deferred.resolve();
      };
    }
    catch
    {
        deferred.reject();
    }

    return deferred.promise;
  ]);

Um ein gelöstes Versprechen zurückzugeben, können Sie Folgendes verwenden:

return $q.defer().resolve();

Wenn Sie etwas auflösen oder Daten zurückgeben müssen:

return $q.defer().resolve(function(){

    var data;
    return data;

});

Hier ist der richtige Code für Ihren Service:

myApp.service('userService', [
  '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {

    var user = {
      access: false
    };

    var me = this;

    this.initialized = false;
    this.isAuthenticated = function() {

      var deferred = $q.defer();
      user = {
        first_name: 'First',
        last_name: 'Last',
        email: '[email protected]',
        access: 'institution'
      };
      deferred.resolve(user);
      me.initialized = true;

      return deferred.promise;
    };
  }
]);

Dann sollte sich Ihr Controller entsprechend ausrichten:

myApp.run([
  '$rootScope', 'userService', function($rootScope, userService) {
    return userService.isAuthenticated().then(function(user) {
      if (user) {
        // You have access to the object you passed in the service, not to the response.
        // You should either put response.data on the user or use a different property.
        return $rootScope.$broadcast('login', user.email);  
      } else {
        return userService.logout();
      }
    });
  }
]);

Einige Punkte zum Service:

  • Stellen Sie in einem Dienst nur das dar, was angezeigt werden muss. Der Benutzer sollte intern aufbewahrt werden und darf nur von Getigern abgerufen werden.

  • Wenn Sie sich in Funktionen befinden, verwenden Sie 'me', den Dienst, um Randfälle davon mit Javascript zu vermeiden.

  • Ich ahnte, was initialisiert werden sollte, fühle mich frei, mich zu korrigieren, wenn ich falsch geraten habe.


Von Ihrer Servicemethode:

function serviceMethod() {
    return $timeout(function() {
        return {
            property: 'value'
        };
    }, 1000);
}

Und in deinem Controller:

serviceName
    .serviceMethod()
    .then(function(data){
        //handle the success condition here
        var x = data.property
    });

Geben Sie Ihr Versprechen zurück, und geben Sie deferred.promise zurück.
Es ist die Versprechen-API, die die "dann" -Methode hat.

https://docs.angularjs.org/api/ng/service/$q

Der Aufruf von resol löst kein Versprechen zurück, sondern signalisiert nur das Versprechen, dass das Versprechen gelöst wird, sodass die 'dann'-Logik ausgeführt werden kann.

Grundmuster wie folgt ausspülen und wiederholen
http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]*" data-semver="1.3.0-beta.5" 
        src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>

<div ng-controller="test">
  <button ng-click="test()">test</button>
</div>
<script>
  var app = angular.module("app",[]);

  app.controller("test",function($scope,$q){

    $scope.$test = function(){
      var deferred = $q.defer();
      deferred.resolve("Hi");
      return deferred.promise;
    };

    $scope.test=function(){
      $scope.$test()
      .then(function(data){
        console.log(data);
      });
    }      
  });

  angular.bootstrap(document,["app"]);

</script>


Das ist mein grundlegendes Verständnis. Es kann durchaus falsch sein!

  1. Elemente werden überwacht, indem eine Funktion (die das zu überwachende Objekt zurückgibt) an die $watch Methode übergeben wird.
  2. Änderungen an beobachteten Elementen müssen innerhalb eines Codeblocks vorgenommen werden, der von der Methode $apply umschlossen wird.
  3. Am Ende von $apply die $digest Methode aufgerufen, die jeden der Watts durchläuft und prüft, ob sie sich seit dem letzten Aufruf von $digest geändert haben.
  4. Wenn irgendwelche Änderungen gefunden werden, wird der Digest erneut aufgerufen, bis sich alle Änderungen stabilisiert haben.

Bei der normalen Entwicklung teilt die Datenbindungssyntax im HTML dem AngularJS-Compiler mit, dass er die Uhren für Sie erstellen soll, und Controller-Methoden werden bereits in $apply . Also für den Anwendungsentwickler ist alles transparent.





javascript angularjs promise angular-promise