【问题标题】:class scope is lost within the ajax success callback类范围在 ajax 成功回调中丢失
【发布时间】:2016-09-10 07:07:22
【问题描述】:

我有使用 TypeScript 编码的简单控制器和服务类。但是,从 ajax($http 服务)的成功回调中,该关键字的值是未定义的。所以代码在(控制器类的)行代码处抛出异常:

this._$location.path('/index'); // 错误:this 的值未定义

请帮我解决这个问题。

控制器代码:(异常发生在方法“login(): void”中)

/// <reference path="../../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../services/loginsrvc.ts" />

module angularWithTs {

    "use strict";


    export class LoginCtrl {
        static $inject = ["LoginSrvc", "SessionSrvc", "$location"];

        username: string;
        password: string;
        errorMessage: string;

        _loginSrvc: LoginSrvc;
        _sessionSrvc: SessionSrvc;
        _$location: ng.ILocationService; 

        constructor(loginSrvc: LoginSrvc, sessionSrvc: SessionSrvc, $location: ng.ILocationService) {
            this.username = "undefined";
            this.password = "undefined";
            this.errorMessage = "undefined";

            this._loginSrvc = loginSrvc;
            this._sessionSrvc = sessionSrvc;
            this._$location = $location;
        }

        login(): void {

            this._loginSrvc.getToken(this.username, this.password)
                .then(function (response) {
                    SessionSrvc.setToken(response.access_token); // store token in cookies
                    this._$location.path('/index'); // ERROR: the value of this is undefined

                }, function (errorResponse) {
                    //$scope.loginForm.errorMessage = errorResponse.error_description;
                });


        }

    }

    angular.module("angularWithTs").controller("LoginCtrl", LoginCtrl);
}

服务代码:

    /// <reference path="sessionsrvc.ts" />
    /// <reference path="../models/authtoken.ts" />



module angularWithTs {
    "user strict";

    export class LoginSrvc {
        static $inject = ['$http', '$q', 'SessionSrvc'];
        _$http: ng.IHttpService;
        _$q: ng.IQService;
        _sessionSrvc: SessionSrvc;

        constructor($http: ng.IHttpService, $q: ng.IQService, sessionSrvc: SessionSrvc) {
            this._$http = $http;
            this._$q = $q;
            this._sessionSrvc = sessionSrvc;
        }


        getToken(username: string, password: string): ng.IPromise<AuthToken> {
            var result = this._$q.defer();

            var params = { grant_type: "password", userName: username, password: password };

            this._$http({
                method: 'POST',
                url: this._sessionSrvc.apiHost + 'token',
                transformRequest: function (obj) {
                    var str = [];
                    for (var p in obj)
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    return str.join("&");
                },
                data: params,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;' }
                })
                .success(response => {
                    result.resolve(response);
                })
                .error(errorResponse => {
                    result.reject(errorResponse);
                });

            return result.promise;
        }    
    }

    angular.module("angularWithTs").service("LoginSrvc", LoginSrvc);
}

【问题讨论】:

    标签: angularjs typescript


    【解决方案1】:

    在这部分:

    this._loginSrvc.getToken(this.username, this.password)
        .then(function (response) {
            SessionSrvc.setToken(response.access_token); // store token in cookies
            this._$location.path('/index'); // ERROR: the value of this is undefined
        }, function (errorResponse) {
            //$scope.loginForm.errorMessage = errorResponse.error_description;
        });
    

    您传递了两个函数作为 promise 的解析/拒绝,但这些函数不保存 this 的上下文。

    你可以传arrow functions:

    this._loginSrvc.getToken(this.username, this.password)
        .then((response) => {
            SessionSrvc.setToken(response.access_token); // store token in cookies
            this._$location.path('/index'); // ERROR: the value of this is undefined
        }, (errorResponse) => {
            //$scope.loginForm.errorMessage = errorResponse.error_description;
        });
    

    或者使用bind:

    this._loginSrvc.getToken(this.username, this.password)
        .then(function (response) {
            SessionSrvc.setToken(response.access_token); // store token in cookies
            this._$location.path('/index'); // ERROR: the value of this is undefined
        }.bind(this), function (errorResponse) {
            //$scope.loginForm.errorMessage = errorResponse.error_description;
        });
    

    【讨论】:

    • 谢谢尼赞·托默。顺便说一句,我不知道“函数(响应)”和箭头函数(=>)之间的区别。它们似乎是匿名函数,不是吗?
    • 在 javascript 中,如果函数没有名称,则它是匿名的,即:function() { ... }。箭头函数始终是匿名的。不同之处在于,使用箭头函数,this 的范围与普通函数不同。
    猜你喜欢
    • 2011-11-11
    • 2010-12-06
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    相关资源
    最近更新 更多