从公共服务调用函数时,未定义TypeScript服务

时间:2016-08-22 08:35:30

标签: angularjs typescript

我正在使用带有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函数,我该如何解决?我做错了什么?

2 个答案:

答案 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)

@Dawood,你失去了语境,我的朋友。导致此问题的原因是您将函数(loginCompleted,loginFailed)作为参数发送,并且在执行与其他对象链接的关键字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);
            });
    }

 }
}