TypeScript class function not available

爷,独闯天下 提交于 2019-12-20 20:37:20

问题


I'm trying to call a instance method of a TypeScript class (in an ASP.NET MVC project). However, at Runtime I get exceptions like 0x800a01b6 - JavaScript runtime error: Object doesn't support property or method 'checkString'.

I copied the generated JavaScript in a jsfiddle where the method seems to work.
I'm not really a JavaScript guy, so any help is much appreciated!

Things I have tried so far:

  1. different browsers (Chrome: Uncaught TypeError: undefined is not a function, FF: TypeError: this.checkString is not a function)
  2. clearing browser caches
  3. deleting the temporary files of IIS Express
  4. cleaning and rebuilding the solution
  5. not using the private modifier
  6. starting the project on another machine
  7. replacing the underscore.js call with a dummy to verfiy that's not the problem
  8. checked that the instance members are correctly set

This is the TypeScript code:

class FormData {
    BlogName: string;
    CacheTimeOut: number;
    CopyrightHolder: string;
    NavBarTitle: string;
    MarkdownExtra: boolean;
    MarkdownSanitize: boolean;
    RatingActive: boolean;
    HtmlEditor: boolean;

    constructor(blogName: string, cacheTimeOut: number, copyrightHolder: string, navBarTitle: string, markdownExtra: boolean, markdownSanitize: boolean, ratingActive: boolean, htmlEditor: boolean) {
        this.BlogName = blogName;
        this.CacheTimeOut = cacheTimeOut;
        this.CopyrightHolder = copyrightHolder;
        this.NavBarTitle = navBarTitle;
        this.MarkdownExtra = markdownExtra;
        this.MarkdownSanitize = markdownSanitize;
        this.RatingActive = ratingActive;
        this.HtmlEditor = htmlEditor;
    }

    private checkString(value: string): boolean {
        return _.isString(value) && value !== '';
    }

    validate(): boolean {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    }       
}

//I'm calling the validate function like that (from within the same module)
var form = getFormData(); //returns a FormData instance
if (!form.validate()) {
    //foo
}

And here the generated JavaScript:

var FormData = (function () {
    function FormData(blogName, cacheTimeOut, copyrightHolder, navBarTitle, markdownExtra, markdownSanitize, ratingActive, htmlEditor) {
        this.BlogName = blogName;
        this.CacheTimeOut = cacheTimeOut;
        this.CopyrightHolder = copyrightHolder;
        this.NavBarTitle = navBarTitle;
        this.MarkdownExtra = markdownExtra;
        this.MarkdownSanitize = markdownSanitize;
        this.RatingActive = ratingActive;
        this.HtmlEditor = htmlEditor;
    }
    FormData.prototype.checkString = function (value) {
        return _.isString(value) && value !== '';
    };

    FormData.prototype.validate = function () {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    };
    return FormData;
})();

回答1:


This is probably because of the wrong this at runtime. You can use a lambda function ()=>{} instead of function to make sure that the this is lexically scoped in the generated JavaScript:

validate = (): boolean => {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    } 

Please search for what this means in javascript and typescript to learn more.




回答2:


Another Bypass-Style Solution:
instead of using this., you can use super..

  • A prerequisite is to create two classes, one as a Base Class, another as a Usable Class.
  • The Base Class contains the methods that you want to call in the constructor.
  • The Usable Class calls the Method from within it's constructor using super.myMethod(); instead of this.myMethod();

This is a subtle benefit made easily possible thanks to Typescript. :)

Example:
Source: Typescript Bypass Solution on Stackoverflow

export class myBaseClass
{
    constructor(ctx:any)
    {
        this.ctx = ctx;         // Audio context saved into member variable of class
    }
    myBaseMethod()
    {
        // Do Complex Work
    }
}

export class myUsableClass extends myBaseClass
{
    constructor(ctx:any)
    {
        super(ctx);
        super.myBaseMethod(); // Use super., Not this.
    }

}


来源:https://stackoverflow.com/questions/23058794/typescript-class-function-not-available

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!