2015-12-10 75 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); 
}); 

任何问题,只是问