类成员变得不确定

时间:2014-12-10 11:47:00

标签: class typescript undefined typeerror member

我对TypeScript很陌生,目前我遇到了一个奇怪的问题。当文档准备就绪时,我使用JQuery创建一个主类的实例。

var main: MainApp;
$(document).ready(function () {
   main = new MainApp();
});

简化的 MainApp 类:

class MainApp {
   // Helper Objects
   net: AppNetworking;
   urlHelper: UrlHelper;
   cat: Category;

   // Construction
   constructor() {
      this.net = new AppNetworking();
      this.urlHelper = new UrlHelper();
   }

   // Ajax Callback with Data needed to initialize the "cat" object
   private AjaxCallback(categoryData){
      this.cat = new Category(categoryData);
   }

   // Event Handler for an HTML-Element
   // As it would be called anonymously in JS I decided to make it a static function
   static onClickSendButton(): void{
      // Using some members of the MainApp
      var hostUrl: string = main.urlHelper.getQueryStringParam("HostUrl");

      if (main.cat.isValidCategory()) {
         main.sendCategory();
      }
   }

   sendCategory(): boolean {
      // Some logic to send data via AJAX
   }
}

该函数正在构建MainApp类时注册到按钮的 onClick 事件。

$("#btnSendCat").click(MainApp.onClickSendButton);

调用函数onClickSendButton()时,会产生错误:

Uncaught TypeError: Cannot read property 'isValidCategory' of undefined

调试时,urlHelper实例已定义,但cat实例未定义。因为我没有在我的应用程序中的任何地方触摸实例cat,所以我真的很困惑它是如何未定义的。另外,在检查main变量时,所有成员都已定义!

我在这里做违法的事吗?该代码可能存在问题吗?

2 个答案:

答案 0 :(得分:1)

完全修改答案。我实际上回答了这个错误的两种最常见的情况,但实际上你的问题是不同的。

通常的答案是

  1. 确保您引用的是.js个文件,而不是.ts个文件
  2. 确保以正确的顺序加载脚本
  3. 在您的情况下,这不是问题,您的代码足以重新创建问题。

    我已经完成了以下测试,填写了空白 - 它按预期工作。

    app.ts

    declare var main: MainApp;
    
    class AppNetworking {
    
    }
    
    class UrlHelper {
        getQueryStringParam(input: string) {
            console.log('Got here getQueryStringParam');
            return input;
        }
    }
    
    class Category {
        isValidCategory() {
            console.log('Got here isValidCategory');
            return true;
        }
    }
    
    class MainApp {
       // Helper Objects
       net: AppNetworking;
       urlHelper: UrlHelper;
       cat: Category;
    
       // Construction
       constructor() {
          this.net = new AppNetworking();
          this.cat = new Category();
          this.urlHelper = new UrlHelper();
       }
    
       // Event Handler for an HTML-Element
       // As it would be called anonymously in JS I decided to make it a static function
       static onClickSendButton(): void{
          // Using some members of the MainApp
          var hostUrl: string = main.urlHelper.getQueryStringParam("HostUrl");
    
          if (main.cat.isValidCategory()) {
             main.sendCategory();
          }
       }
    
       sendCategory(): boolean {
           // Some logic to send data via AJAX
           return true;
       }
    }
    

    index.html snip

    <div id="btnSendCat">BTN SEND CAT</div>
    <script src="app.js"></script>
    <script src="Scripts/jquery-2.1.1.min.js"></script>
    <script>
        var main;
        $(document).ready(function () {
            main = new MainApp();
            $("#btnSendCat").click(MainApp.onClickSendButton);
        });
    </script>
    

    运行此测试的结果是控制台窗口中的以下输出:

    "Got here getQueryStringParam" app.js:10
    "Got here isValidCategory" app.js:19
    

答案 1 :(得分:1)

我离开了我的应用程序的一些重要部分,对不起。在项目的后期,我曾经重新初始化该类别对象。这种重新初始化是在AJAX-Callback Function中完成的。此函数在我的对象之外运行,而this不是我的MainApp类,而是Window。我认为这就是你在JavaScript中所谓的匿名函数

我通过使用全局main变量

解决了这个问题
class MainApp {
   // Called anonymous so it should be a static function
   private AjaxCallback(categoryData){
      // this.cat = new Category(categoryData);  ! this will be the Window Instance and not a MainApp Instance

      main.cat = new Category(categoryData); // Initialization using the "main" variable
   }
}

我的onClickSendButton方法this.cat中的调用现在成功,因为this.cat已正确重新初始化。

这段视频在我的研究中给了我很多帮助:Understanding "this" in TypeScript