2015-12-10 115 views
-1

我做了一個服務,它使用$ http發佈登錄數據並獲取身份驗證令牌,但每當我將其注入到控制器時,它就會中斷(看起來像html沒有看到它)。當我刪除服務注入,或注入一個使用$資源,而不是,一切工作正常。 下面是該服務的代碼:

MyApp.service('LoginSrv', ['$http', function User($http) { 
     var userData = { 
     isAuthenticated: false, 
     username: '', 
     bearerToken: '', 
     expirationDate: null, 
     }; 

    function setHttpAuthHeader() { 
      $http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken; 
     } 

    this.getUserData = function(){ 
     return userData; 
}; 

this.authenticate = function(username, password, successCallback, errorCallback) { 
     var config = { 
      method: 'POST', 
      url: '/accounts/login', 
      headers: { 
        'Content-Type': 'application/x-www-form-urlencoded', 
       }, 
     data: 'grant_type=password&username=' + username + '&password=' + password, 
     }; 

    $http(config) 
    .success(function(data) { 
      userData.isAuthenticated = true; 
      userData.username = data.userName; 
      userData.bearerToken = data.access_token; 
      userData.expirationDate = new Date(data['.expires']); 
      setHttpAuthHeader(); 
      if (typeof successCallback === 'function') { 
       successCallback(); 
       } 
     }) 
    .error(function(data) { 
      if (typeof errorCallback === 'function') { 
       if (data.error_description) { 
         errorCallback(data.error_description); 
        } else { 
        errorCallback('Unable to contact server; please, try again later.'); 
       } 
      } 
    }); 
}; 
    }]); 

這裏是控制器代碼:

MyApp.controller('mainCtrl', function ($scope, LoginSrv) 
{ 
    $scope.loginUsername = 'Jan'; 
    $scope.loginPassword = 'Maria'; 
    $scope.userLogin = new LoginSrv(); 
    $scope.loginError = false; 
    function onSuccesfulLogin() {}; 
    function onFailedLogin(error) {}; 
    $scope.login = function() { 
     userLogin.authenticate($scope.loginUsername, $scope.loginPassword, onSuccesfulLogin, onFailedLogin); 
    }; 

}); 
+0

什麼錯誤,你接受?你是什​​麼意思html沒有看到它? – user2954587

+0

爲什麼你要做'功能用戶($ http)'而不是'function($ http)'? – RPGillespie

+0

另外你爲什麼混合注射樣式?在您的控制器中,您正在使用直接注射,但在您的服務中,您正在使用小型化注射。 – RPGillespie

回答

1

Services are singleton so you need not give a "new"

我讓你需要同樣的流程簡單例子,效果不錯,我希望對您有所幫助:

The Service

angular.module("yourapp").factory('LoginSrv', function User($http) { 
     var _authenticate = function(username, password) { 
      console.log('logged') 
     }; 
     return { 
      authenticate: _authenticate 
     }; 
}); 

The Controller

angular.module("yourapp").controller('mainCtrl', function ($scope, $http, LoginSrv) 
     { 
      $scope.loginUsername = 'Jan'; 
      $scope.loginPassword = 'Maria'; 
      $scope.userLogin = LoginSrv; 
      $scope.loginError = false; 
      $scope.login = function() { 
       userLogin.authenticate($scope.loginUsername, $scope.loginPassword); 
      }; 
}); 
1

對方回答做了解釋你的LoginSrv相關的異常的好工作,並說明如何實現服務/工廠。然而,它沒有注意到兩者之間的差異。

當你注入將作爲調用工廠函數的結果提供了返回值工廠。

服務 當你注入將提供服務功能的實例的服務。這與new serviceFunction();類似。注意角度是很重要的,第一次注入服務時,所有其他時間注入的服務都會收到相同的實例。

所以工廠是用於創建對象(因此名稱)和服務的意思,以及服務。所以共享邏輯。

所以在我看來(就是這樣),你現有的服務正試圖做到這一點。您似乎有一個您想創建的用戶對象,但也包含用於驗證用戶的方法。最好將該用戶對象放入工廠,該工廠返回創建方法以創建新用戶。然後將認證邏輯放入一個服務中。然後,您的身份驗證不會直接耦合到您的用戶實施。

可能實現(僞代碼)

.factory('userFactory', function() { 
    return { 
     create: function (details) { 
      return Object.create({}, { 
       username: { 
        value: details.username 
       }, 
       password: { 
        value: details.password 
       }, 
       isAuthenticated: { 
        value: false 
       } 
      }); 
     } 
    } 
}); 

.service('auth', function ($http) { 
    this.authenticate = function (username, password) { 
     //Build config 
     return $http(); 
    } 
}); 

.controller('test', function ($scope, userFactory, auth) { 
    var user = userFactory.create({ 
     username: 'hiya', 
     password: 'epic secrets' 
    }); 

    auth.authenticate(user.username, user.password) 
     .then(function (d) { 
      user.isAuthenticated = d.isAuthenticated; 
     }) 
     .catch(SomeGenericErrorHandler); 
}); 

任何問題,只是問