我正在使用带有Angular JS的TypeScript来编写一个公共服务,该服务将处理对服务器的POST和GET请求。
这就是服务的样子:
module TBApp {
export class apiService {
static $inject = ['$http', 'notificationService'];
constructor(private $http, private notificationService: notificationService) {
}
get(url, config, success, failure) {
return this.$http.get(url, config)
.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}
post(url, data, success, failure) {
return this.$http.post(url, data)
.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}
handleResponse(result, success) {
this.notificationService.displaySuccess(result.data.message);
success(result);
}
handleError(result, failure) {
if (result.status === '401') {
this.notificationService.displayError('Authentication required.');
//TODO: redirect to login page
}
else if (failure !== null) {
failure(result);
}
}
}
}
所以在下面显示的控制器中,我想在登录成功时调用loginCompleted
。
module TBApp {
export class loginController extends MyApp.BaseController {
membershipService: membershipService;
apiService: apiService;
static $inject = ['$scope', 'membershipService', 'apiService', '$location'];
constructor($scope, membershipService: membershipService, apiService: apiService, private $location) {
super($scope);
this.scope.user = new User(null, null);
this.membershipService = membershipService;
this.apiService = apiService;
}
login() {
// HERE: this.membershipService Is NOT NULL OR UNDEFINED
console.log(this.membershipService);
this.apiService.post('/api/account/authenticate', this.scope.user, this.loginCompleted, this.loginFailed);
}
loginCompleted(response) {
//This method will save the logged in user to cookies
//HERE : this.membershipService Is UNDEFINED
this.membershipService.saveCredentials(this.scope.user);
// redirect to home page
this.$location.path('/');
}
loginFailed(response) {
alert('login failed');
console.log(response);
}
}
}
函数被调用一切正常,除了this.membershipService
函数内未定义loginCompleted()
。
我认为这是因为从loginCompleted()
内部调用apiService
函数,我该如何解决?我做错了什么?
答案 0 :(得分:2)
应该是
this.apiService.post(
'/api/account/authenticate',
this.scope.user,
this.loginCompleted.bind(this), this.loginFailed.bind(this)
)
可替换地,
this.loginCompleted = this.loginCompleted.bind(this)
this.loginFailed = this.loginFailed.bind(this)
可以在构造函数中完成所有回调/处理程序方法
答案 1 :(得分:2)
this
时。
你可以在这里做什么 - 你可以发送带有绑定上下文的函数(它将始终设置为你定义为第一个参数的对象)。
module TBApp {
export class loginController extends MyApp.BaseController {
static $inject: string[] = ['$scope', 'membershipService', 'apiService', '$location'];
constructor(
private $scope: ng.IScope,
private membershipService: membershipService,
private apiService: apiService,
private $location
) {
super($scope);
this.scope.user = new User(null, null);
}
login() {
// HERE: this.membershipService Is NOT NULL OR UNDEFINED
console.log(this.membershipService);
this.apiService.post('/api/account/authenticate', this.scope.user, this.loginCompleted.bind(this), this.loginFailed.bind(this));
}
loginCompleted(response) {
//This method will save the logged in user to cookies
//HERE : this.membershipService Is UNDEFINED
this.membershipService.saveCredentials(this.scope.user);
// redirect to home page
this.$location.path('/');
}
loginFailed(response) {
alert('login failed');
console.log(response);
}
}
}
在这种情况下,您发送带有绑定上下文的函数:
this.loginCompleted.bind(this)
this.loginFailed.bind(this)
将使用绑定上下文创建两个新函数到当前类。
有关此主题的更多信息:understanding context in js
P.S。不要责怪我,我改变了一些代码风格。希望我的回答能有所帮助
以下更新的代码与评论对话相关
module TBApp {
export class loginController extends MyApp.BaseController {
static $inject: string[] = ['$scope', 'membershipService', 'apiService', '$location'];
constructor(
private $scope: ng.IScope,
private membershipService: membershipService,
private apiService: apiService,
private $location
) {
super($scope);
this.scope.user = new User(null, null);
}
login() {
// HERE: this.membershipService Is NOT NULL OR UNDEFINED
console.log(this.membershipService);
this.apiService.post('/api/account/authenticate', this.scope.user,
(response) => {
this.membershipService.saveCredentials(this.scope.user);
// redirect to home page
this.$location.path('/');
},
(response) => {
alert('login failed');
console.log(response);
});
}
}
}