2014-05-09 80 views
32

我的服務是:

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(); 
    }; 
    } 
]); 

我通過呼叫這在我的config文件:

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(); 
     } 
    }); 
    } 
]); 

然而,抱怨說then不是一個函數。我不是在回覆已解決的承諾嗎?

回答

17

從您的服務方法:

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

而在你的控制器:

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

@BenjaminGruenbaum是的,你是正確的,我不知道'$超時'實際上返回一個承諾,serviceMethod可以縮短爲:返回$超時(函數(){返回{屬性:'值'};},1000); – Brocco

+7

這可能會起作用,但它肯定不是推薦的方法來返回承諾 –

+0

@BenjaminGruenbaum我做了,現在返回$超時產生的承諾。 – Brocco

31

返回您的承諾,返回deferred.promise。
它是具有'then'方法的promise API。

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

調用的決心不會返回一個承諾,只發信號給 承諾,承諾解決,因此它可以執行「然後」的邏輯。

基本格局如下,沖洗和重複
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> 

+0

如何將承諾得到解決呢?在您返回deferred.promise之前,'.then'永遠不會被觸發 – Shamoon

+2

您解決延遲。 – mccainz

+0

@Shamoon deferred.resolve();在你調用它的那一刻被解決,因爲沒有給定的值。我會建議而不是寫deferred.resolve(「Hi」);只需編寫deferred.resolve();獲得解決的空洞承諾。但是你也可以使用$ q.when();得到一個解決可靠的空承諾;-)。 – Sebastian

0

試試這個:

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; 
    ]); 
+0

有人能告訴我爲什麼這是標記爲downvote? – premsh

2

這裏是爲您服務的正確代碼:

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; 
    }; 
    } 
]); 

然後你控制器應相應調整:

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(); 
     } 
    }); 
    } 
]); 

幾點需要注意有關服務:

  • 僅在服務中暴露需要暴露的內容。用戶應保存在內部,並且只能由獲取者訪問。

  • 在函數中,使用'我'這是服務,以避免與JavaScript的邊緣情況。

  • 我猜想初始化的意思是什麼,如果我猜錯了,請隨時糾正我。

1

對於較短的JavaScript代碼中使用此:

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; 
    }; 
    } 
]); 

你知道你用一個新對象覆蓋它,而不是隻設置對象的屬性鬆結合userService.user?

這是我的意思,作爲我的plnkr的一個例子。聯合代碼示例(工作示例: 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; 
     }); 
    }; 
}]); 
1

要返回一個解決的承諾,你可以使用:

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

如果您需要解決的東西或返回數據:

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

    var data; 
    return data; 

}); 
+0

我已經[發佈](http://stackoverflow.com/a/30779102/901944)甚至更短的版本。 –

82

如何簡單地在Angular中返回預先解決的承諾

解決的承諾:

return $q.when(someValue); // angular 1.2+ 
return $q.resolve(someValue); // angular 1.4+, alias to `when` to match ES6 

拒絕承諾:

return $q.reject(someValue); 
+1

這正是我正在尋找的。在存儲http服務調用時返回一個靜態值的簡短方法。 – Richard