为什么变量是未定义在所述方法,但它不是在打字稿构造 [英] Why the variable is undefined in the method but it is not in the constructor in Typescript

查看:125
本文介绍了为什么变量是未定义在所述方法,但它不是在打字稿构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发使用1.4.9 Angularjs以打字稿的应用程序。

我有一个控制器,它有testManagementService服务注入了testManagementService变量是在构造一个对象,但它是在其被调用的方法未定义。奇怪的是,我在与其他服务另一个控制器相同的设置,这是工作的罚款。

问题:


  • 有与标签testmgmgservice的构造函数的console.log,它说testManagementService变量是具有getTestSuiteTree方法的Restangular对象

  • 控制台日志中readRepository方法,它是通过/由kendo.data.TreeListDataSource管理叫,说this.testManagementService是不确定的。

在这里输入的形象描述

我做了什么至今:


  • 我已经检查了语法,有可能我已经错过了一些东西 - >没有

  • 我已经改变了变量名称不同的东西,以检查是否有这将覆盖它的一些其他的变量 - >相同的结果

  • 我有一个长时间的睡眠,有时帮助 - >有没有新的想法

  • 我已经编制了code用Vs2013和VS2015 - >相同的结果

服务

模块sayusiando.gonogo.web.spa.service {
    进口IGeneralTestSuitTestCaseContract = sayusiando.gonogo.web.spa.common.contracts.IGeneralTestSuitTestCaseContract;
    使用严格的;    导出接口ITestManagementService {        getTestSuitTree():ng.IPromise< IGeneralTestSuitTestCaseContract []取代;    }    类TestManagementService实现ITestManagementService {        //#构造函数区域
        构造函数(
            私人Restangular:restangular.IService
        ){}
        //#endregion        公共getTestSuitTree():ng.IPromise&下; IGeneralTestSuitTestCaseContract []≥ {            VAR资源= this.Restangular.all(的TestSuite / GetTestSuiteTree);            返回<&任何GT; resource.getList();        }    }    。工厂$注射= [Restangular];    功能工厂(Restangular:restangular.IService){
        返回新TestManagementService(Restangular);
    }    角
        .module(goNoGo)
        .factory(testManagementService,工厂);}

控制器

模块sayusiando.gonogo.web.spa.mainpage.showtestsuittree.controllers {
    进口IGeneralTestSuitTestCaseContract = sayusiando.gonogo.web.spa.common.contracts.IGeneralTestSuitTestCaseContract;
    进口DataSourceTransport = kendo.data.DataSourceTransport;
    进口DataSourceSchema = kendo.data.DataSourceSchema;
    进口DataSourceSchemaModelFields = kendo.data.DataSourceSchemaModelFields;
    进口TestManagementService = sayusiando.gonogo.web.spa.service.ITestManagementService;
    使用严格的;    导出接口IShowTestSuitTreeController {
        激活:()=>无效;
    }    类ShowTestSuitTreeController实现IShowTestSuitTreeController {        //#区域变量
        testSuiteTree = [];
        testSuiteTreeKendoTreeListOptions:kendo.ui.TreeListOptions = {};
        //#endregion        //#区域注入和构造函数
        静态$注射:字符串[] = ['testManagementService'];        构造函数(
            私人testManagementService:gonogo.web.spa.service.ITestManagementService
        ){            的console.log('testmgmgservice',testManagementService);            this.activate();        }
        //#endregion        激活(){无效            VAR dataSourceTransport =< D​​ataSourceTransport> {
                阅读:this.readRepository
            };            VAR模式:DataSourceSchema =< D​​ataSourceSchema> {
                型号:{
                    ID:ID,
                    parentId的:parentId的
                    字段:或其可DataSourceSchemaModelFields> {                        ID:{类型:数字,编辑:假的,可为空:真},
                        名称:{类型:字符串,编辑:假的,可为空:真}                    }                }            };            VAR数据源=新kendo.data.TreeListDataSource({
                交通:dataSourceTransport,
                模式:模式,
                批:真
            });
            VAR idColumn:kendo.ui.TreeListColumn =< kendo.ui.TreeListColumn> {
                现场:ID,
                宽度:100像素
            };
            VAR名称列:kendo.ui.TreeListColumn =< kendo.ui.TreeListColumn> {
                现场:姓名,
                宽度:400像素
            };            this.testSuiteTreeKendoTreeListOptions.dataSource =数据源;
            this.testSuiteTreeKendoTreeListOptions.sortable = FALSE;
            this.testSuiteTreeKendoTreeListOptions.editable = FALSE;
            this.testSuiteTreeKendoTreeListOptions.columns = [
                idColumn,
                名称列
            ];        }        readRepository(E):任何{            的console.log('testmgmt2',this.testManagementService);
            。this.testManagementService.getTestSuitTree(),然后((结果:数组< IGeneralTestSuitTestCaseContract>):无效=> {
                e.success(结果);
            },(原因:任意):无效=> {
                e.error(原因);
            });            返回e的;
        }    }    角
        .module(goNoGo)
        .controller(showTestSuitTreeController,ShowTestSuitTreeController);
}

从控制器生成的JavaScript

VAR sayusiando;
(函数(sayusiando){
    VAR gonogo;
    (函数(gonogo){
        VAR网络;
        (函数(网络){
            VAR水疗;
            (函数(SPA){
                VAR炫魅;
                (函数(炫魅){
                    VAR showtestsuittree;
                    (函数(showtestsuittree){
                        VAR控制器;
                        (函数(控制器){
                            使用严格的;
                            VAR ShowTestSuitTreeController =(函数(){
                                功能ShowTestSuitTreeController(testManagementService){
                                    this.testManagementService = testManagementService;
                                    //#区域变量
                                    this.testSuiteTree = [];
                                    this.testSuiteTreeKendoTreeListOptions = {};
                                    的console.log('testmgmgservice',testManagementService);
                                    this.activate();
                                }
                                //#endregion
                                ShowTestSuitTreeController.prototype.activate =功能(){
                                    VAR dataSourceTransport = {
                                        阅读:this.readRepository
                                    };
                                    VAR模式= {
                                        型号:{
                                            ID:ID,
                                            parentId的:parentId的
                                            字段:{
                                                ID:{类型:数字,编辑:假的,可为空:真},
                                                名称:{类型:字符串,编辑:假的,可为空:真}
                                            }
                                        }
                                    };
                                    VAR数据源=新kendo.data.TreeListDataSource({
                                        交通:dataSourceTransport,
                                        模式:模式,
                                        批:真
                                    });
                                    VAR idColumn = {
                                        现场:ID,
                                        宽度:100像素
                                    };
                                    VAR名称列= {
                                        现场:姓名,
                                        宽度:400像素
                                    };
                                    this.testSuiteTreeKendoTreeListOptions.dataSource =数据源;
                                    this.testSuiteTreeKendoTreeListOptions.sortable = FALSE;
                                    this.testSuiteTreeKendoTreeListOptions.editable = FALSE;
                                    this.testSuiteTreeKendoTreeListOptions.columns = [
                                        idColumn,
                                        名称列
                                    ];
                                };
                                ShowTestSuitTreeController.prototype.readRepository =功能(E){
                                    的console.log('testmgmt2',this.testManagementService);
                                    this.testManagementService.getTestSuitTree()。​​然后(功能(结果){
                                        e.success(结果);
                                    },函数(原因){
                                        e.error(原因);
                                    });
                                    返回e的;
                                };
                                //#endregion
                                //#区域注入和构造函数
                                。ShowTestSuitTreeController $注射= ['testManagementService'];
                                返回ShowTestSuitTreeController;
                            })();
                            角
                                .module(goNoGo)
                                .controller(showTestSuitTreeController,ShowTestSuitTreeController);
                        })(控制器= showtestsuittree.controllers ||(showtestsuittree.controllers = {}));
                    })(showtestsuittree = mainpage.showtestsuittree ||(mainpage.showtestsuittree = {}));
                })(炫魅= spa.mainpage ||(spa.mainpage = {}));
            })(温泉= web.spa ||(web.spa = {}));
        })(网页= gonogo.web ||(gonogo.web = {}));
    })(gonogo = sayusiando.gonogo ||(sayusiando.gonogo = {}));
})(sayusiando ||(sayusiando = {}));
//#sourceMappingURL = showTestSuitTreeController.js.map


解决方案

我是pretty确定问题是,你传递函数引用了这里的框架:

  VAR dataSourceTransport =< D​​ataSourceTransport> {
      阅读:this.readRepository
  };

这样做,你正在失去上下文(这一点)。当库调用您的readRepository功能,它不再适用于您事先定义​​的函数的上下文。因此, testManagementService 不存在这个当函数被调用。

您可以解决这个问题,通过像这样绑定到正确的上下文:

  VAR dataSourceTransport =< D​​ataSourceTransport> {
      阅读:this.readRepository.bind(本)
  };

或通过捕捉这种传递引用时使用箭头功能

  VAR dataSourceTransport =< D​​ataSourceTransport> {
      阅读:(E)=> this.readRepository(五)
  };

或通过使回调箭头函数本身,保持登记为是。要注意的影响,作为函数则没有更多的样机上注册。

  readRepository =(E)=> {
    ...
}

有关更多信息,请查看 HTTPS://basarat.gitbooks。 IO /打字稿/内容/文档/箭头functions.html

I'm developing an application using 1.4.9 Angularjs with Typescript.

I have a controller which have the testManagementService service injected, the testManagementService variable is an object in the constructor, but it is undefined in the method where it is invoked. The odd thing is that, I have the same setup in another controller with another service and it is working fine.

Issue:

  • there is a console.log in the constructor with the label testmgmgservice, it says the testManagementService variable is an Restangular object having the getTestSuiteTree method
  • the console log in the readRepository method, which is called by / managed by kendo.data.TreeListDataSource, says that this.testManagementService is undefined.

What I did so far:

  • I have checked the syntax, it is possible I have missed something --> no
  • I have changed the variable name something different to check whether there is some other variable which overwrites it --> the same result
  • I had a long sleep, sometimes help --> there is no new idea
  • I have compiled the code with both Vs2013 and VS2015 --> same result

the service:

module sayusiando.gonogo.web.spa.service {
    import IGeneralTestSuitTestCaseContract = sayusiando.gonogo.web.spa.common.contracts.IGeneralTestSuitTestCaseContract;
    "use strict";

    export interface ITestManagementService {

        getTestSuitTree(): ng.IPromise<IGeneralTestSuitTestCaseContract[]>;

    }

    class TestManagementService implements ITestManagementService {

        //#region ctor
        constructor(
            private Restangular: restangular.IService
        ) { }
        //#endregion

        public getTestSuitTree(): ng.IPromise<IGeneralTestSuitTestCaseContract[]> {

            var resource = this.Restangular.all("TestSuite/GetTestSuiteTree");

            return <any>resource.getList();

        }

    }

    factory.$inject = ["Restangular"];

    function factory(Restangular: restangular.IService) {
        return new TestManagementService(Restangular);
    }

    angular
        .module("goNoGo")
        .factory("testManagementService", factory);

}

The controller:

module sayusiando.gonogo.web.spa.mainpage.showtestsuittree.controllers {
    import IGeneralTestSuitTestCaseContract = sayusiando.gonogo.web.spa.common.contracts.IGeneralTestSuitTestCaseContract;
    import DataSourceTransport = kendo.data.DataSourceTransport;
    import DataSourceSchema = kendo.data.DataSourceSchema;
    import DataSourceSchemaModelFields = kendo.data.DataSourceSchemaModelFields;
    import TestManagementService = sayusiando.gonogo.web.spa.service.ITestManagementService;
    "use strict";

    export interface IShowTestSuitTreeController {
        activate: () => void;
    }

    class ShowTestSuitTreeController implements IShowTestSuitTreeController {

        //#region Variables
        testSuiteTree = [];
        testSuiteTreeKendoTreeListOptions: kendo.ui.TreeListOptions = {};
        //#endregion

        //#region Inject and ctor
        static $inject: string[] = ['testManagementService'];

        constructor(
            private testManagementService: gonogo.web.spa.service.ITestManagementService
        ) {

            console.log('testmgmgservice', testManagementService);

            this.activate();

        }
        //#endregion

        activate(): void {

            var dataSourceTransport = <DataSourceTransport>{
                read: this.readRepository
            };

            var schema: DataSourceSchema = <DataSourceSchema>{
                model: {
                    id: "id",
                    parentId: "parentId",
                    fields: <DataSourceSchemaModelFields>{

                        id: { type: "number", editable: false, nullable: true },
                        name: { type: "string", editable: false, nullable: true }

                    }

                }

            };

            var dataSource = new kendo.data.TreeListDataSource({
                transport: dataSourceTransport,
                schema: schema,
                batch: true
            });


            var idColumn: kendo.ui.TreeListColumn = <kendo.ui.TreeListColumn>{
                field: "id",
                width: "100px"
            };
            var nameColumn: kendo.ui.TreeListColumn = <kendo.ui.TreeListColumn>{
                field: "name",
                width: "400px"
            };

            this.testSuiteTreeKendoTreeListOptions.dataSource = dataSource;
            this.testSuiteTreeKendoTreeListOptions.sortable = false;
            this.testSuiteTreeKendoTreeListOptions.editable = false;
            this.testSuiteTreeKendoTreeListOptions.columns = [
                idColumn,
                nameColumn
            ];

        }

        readRepository(e): any {

            console.log('testmgmt2', this.testManagementService);
            this.testManagementService.getTestSuitTree().then((result: Array<IGeneralTestSuitTestCaseContract>): void => {
                e.success(result);
            }, (reason: any): void => {
                e.error(reason);
            });

            return e;
        }

    }

    angular
        .module("goNoGo")
        .controller("showTestSuitTreeController", ShowTestSuitTreeController);
}

The generated javascript from the controller:

var sayusiando;
(function (sayusiando) {
    var gonogo;
    (function (gonogo) {
        var web;
        (function (web) {
            var spa;
            (function (spa) {
                var mainpage;
                (function (mainpage) {
                    var showtestsuittree;
                    (function (showtestsuittree) {
                        var controllers;
                        (function (controllers) {
                            "use strict";
                            var ShowTestSuitTreeController = (function () {
                                function ShowTestSuitTreeController(testManagementService) {
                                    this.testManagementService = testManagementService;
                                    //#region Variables
                                    this.testSuiteTree = [];
                                    this.testSuiteTreeKendoTreeListOptions = {};
                                    console.log('testmgmgservice', testManagementService);
                                    this.activate();
                                }
                                //#endregion
                                ShowTestSuitTreeController.prototype.activate = function () {
                                    var dataSourceTransport = {
                                        read: this.readRepository
                                    };
                                    var schema = {
                                        model: {
                                            id: "id",
                                            parentId: "parentId",
                                            fields: {
                                                id: { type: "number", editable: false, nullable: true },
                                                name: { type: "string", editable: false, nullable: true }
                                            }
                                        }
                                    };
                                    var dataSource = new kendo.data.TreeListDataSource({
                                        transport: dataSourceTransport,
                                        schema: schema,
                                        batch: true
                                    });
                                    var idColumn = {
                                        field: "id",
                                        width: "100px"
                                    };
                                    var nameColumn = {
                                        field: "name",
                                        width: "400px"
                                    };
                                    this.testSuiteTreeKendoTreeListOptions.dataSource = dataSource;
                                    this.testSuiteTreeKendoTreeListOptions.sortable = false;
                                    this.testSuiteTreeKendoTreeListOptions.editable = false;
                                    this.testSuiteTreeKendoTreeListOptions.columns = [
                                        idColumn,
                                        nameColumn
                                    ];
                                };
                                ShowTestSuitTreeController.prototype.readRepository = function (e) {
                                    console.log('testmgmt2', this.testManagementService);
                                    this.testManagementService.getTestSuitTree().then(function (result) {
                                        e.success(result);
                                    }, function (reason) {
                                        e.error(reason);
                                    });
                                    return e;
                                };
                                //#endregion
                                //#region Inject and ctor
                                ShowTestSuitTreeController.$inject = ['testManagementService'];
                                return ShowTestSuitTreeController;
                            })();
                            angular
                                .module("goNoGo")
                                .controller("showTestSuitTreeController", ShowTestSuitTreeController);
                        })(controllers = showtestsuittree.controllers || (showtestsuittree.controllers = {}));
                    })(showtestsuittree = mainpage.showtestsuittree || (mainpage.showtestsuittree = {}));
                })(mainpage = spa.mainpage || (spa.mainpage = {}));
            })(spa = web.spa || (web.spa = {}));
        })(web = gonogo.web || (gonogo.web = {}));
    })(gonogo = sayusiando.gonogo || (sayusiando.gonogo = {}));
})(sayusiando || (sayusiando = {}));
//# sourceMappingURL=showTestSuitTreeController.js.map

解决方案

I'm pretty sure the problem is that you are passing the function reference to the framework here:

  var dataSourceTransport = <DataSourceTransport>{
      read: this.readRepository
  };

Doing this, you are losing the context (the this). When the library calls your readRepository function, it no longer works on the context you defined the function beforehand. So, the testManagementService does not exist on this when the function is called.

You can fix this, by binding to the correct context like so:

  var dataSourceTransport = <DataSourceTransport>{
      read: this.readRepository.bind(this)
  };

or by capturing this using an arrow function when passing the reference

  var dataSourceTransport = <DataSourceTransport>{
      read: (e) => this.readRepository(e)
  };

or by making the callback an arrow function itself, keeping the registration as is. Be aware of the implications, as the function then is no more registered on the prototype.

readRepository = (e) => {
    ...
}

For more info, please check https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

这篇关于为什么变量是未定义在所述方法,但它不是在打字稿构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆