为什么在具有http promise的typescript模块中未定义"this"

J K*_*ing 17 javascript angularjs typescript

这是我的第一个打字稿和角度尝试,我遇到了一个问题.

我有一个以下列方式定义的模块控制器(.ts文件):

module app.controllers {
    "use strict"

    import services = app.services;

    export class calendarController {

        calBlock: any;
        deptId: number;
        calSvc: app.services.calendarService;

        static $inject = ["$scope", "calendarService"];

        constructor(isolateScope: directives.calendarScope, calSvc: services.calendarService) {

            this.deptId = isolateScope.deptId;
            this.calSvc = calSvc;

            calSvc.getMonthBlock(12, 2015, 1, this.deptId)
            .then(
                function (response) {
                    //promise fullfilled (regardless of outcome)                
                    this.calBlock = response.data;
                 },
                 function (error) {
                //handle errors
                    alert(error);
                 }   
             );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是此控制器依赖的服务:

module app.services {
    "use strict"
    export class calendarService {

        private _http: ng.IHttpService;

        static $inject = ["$http"];

        constructor(http: ng.IHttpService) {
            this._http = http;            
        }

        getMonthBlock = function (month:number, year:number, calId:number, deptId:number) {

            //initialise service url
            var sURL = _sf.getServiceRoot('KrisisShifts') + "CalendarService/GetMonthCal/" + calId + "/" + deptId + "/" + month + "/" + year;
            //create config object for get function
            var config = {
                URL: sURL,
                method: "GET",
                dataType: 'json',
                headers: {
                    'ModuleId': _sf.getModuleId(),
                    'TabId': _sf.getTabId(),
                    'RequestVerificationToken': _sf.getAntiForgeryValue()
                }
            }
            //return the promise of the http.get function
            return this._http.get(sURL, config);

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题发生在控制器模块的以下行:

this.calBlock = response.data;
Run Code Online (Sandbox Code Playgroud)

问题是是未定义的,因此calBlock也是未定义的,并且jsConsole会抛出错误:

TypeError:无法在shift-calendar-controller.js中设置undefined属性'calBlock'?cdv = 28:14

我相对较新的javascript和angular和打字稿,所以我很难弄清楚为什么" 这个 "是未定义的.我认为它因为它附在一个函数中.

我需要一种方法将reponse.data(来自$ http调用的json数组)分配给我的控制器的typescript类的calBlock属性.有人可以帮助我理解为什么是响应函数内不定,我怎么能访问它?

谢谢

编辑:解决方案基于tymeJV的答案

这是重写的calBlock调用:

            calSvc.getMonthBlock(12, 2015, 1, this.deptId)
            .then((response) => {
                    //promise fullfilled (regardless of outcome)                
                    this.calBlock = response.data;
                },
            (error) => {
                    //handle errors
                    alert(error);
                }   
            );
Run Code Online (Sandbox Code Playgroud)

tym*_*eJV 38

因为this回调中丢失了上下文.使用typescript中的箭头函数来保留上下文!

calSvc.getMonthBlock(12, 2015, 1, this.deptId).then((response) => {

})
Run Code Online (Sandbox Code Playgroud)

  • @NandaKumar-请参阅:https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html (2认同)