2016-01-20 36 views
3

我是TypeScript和Angular的相對新手,所以我可能在這裏做了一些非常基本的錯誤。「this」未定義在使用TypeScript構建的Angular指令中的側鏈接函數中

我想創建一個抽象基類,從中我可以派生出多個指令,每個指令都會實現一個自定義驗證規則。我的代碼編譯好,但在運行時失敗,特別是當它試圖調用this.isValid(...)時,因爲「this」在那個時候未定義。任何人都可以看到這段代碼有什麼問題嗎?

module App.Common.Directives { 
    'use strict'; 

    export abstract class ValidatorBase implements angular.IDirective { 

     require = 'ng-model'; 
     restrict = 'A'; 

     constructor(private validationErrorKey: string) { } 

     link(scope: angular.IScope, el: angular.IAugmentedJQuery, attributes: Directives.IValidatorAttributes, controller: angular.IFormController) { 
      //tsc writes "var _this = this;" here, but this is undefined 
      scope.$watch(attributes.ngModel,() => { 
       const val: string = el.val(); 
       const valid = this.isValid(val, el, scope, attributes, controller); 
       controller.$setValidity(this.validationErrorKey, valid, undefined); 
      }); 
     } 

     abstract isValid(val: any, el?: angular.IAugmentedJQuery, scope?: angular.IScope, attributes?: Directives.IValidatorAttributes, controller?: angular.IFormController): boolean; 

    } 
} 

下面是從打字稿編譯器的輸出爲此類:

var App; 
(function (App) { 
    var Common; 
    (function (Common) { 
     var Directives; 
     (function (Directives) { 
      'use strict'; 
      var ValidatorBase = (function() { 
       function ValidatorBase(validationErrorKey) { 
        this.validationErrorKey = validationErrorKey; 
        this.require = 'ng-model'; 
        this.restrict = 'A'; 
       } 
       ValidatorBase.prototype.link = function (scope, el, attributes, controller) { 
        var _this = this; //this is undefined when we get here 
        scope.$watch(attributes.ngModel, function() { 
         var val = el.val(); 
         var valid = _this.isValid(val, el, scope, attributes, controller); 
         controller.$setValidity(_this.validationErrorKey, valid, undefined); 
        }); 
       }; 
       return ValidatorBase; 
      })(); 
      Directives.ValidatorBase = ValidatorBase; 
     })(Directives = Common.Directives || (Common.Directives = {})); 
    })(Common = App.Common || (App.Common = {})); 
})(App || (App = {})); 
+0

好像我已經完全複製了這個問題:

如果你不確定詞彙this或要覆蓋它使用箭頭功能http://stackoverflow.com/questions/34561415/why- is-this-null-in-the-link-function-within-an-angular-directive - 現在就去試試這個解決方案。 – wwarby

+0

根據其他工作問題更改TypeScript中鏈接方法的語法。 – wwarby

回答

2

在角指令是不安全的考慮this一個類的實例,因爲功能可以有自己的詞彙this,他們實際上有它。

this是在controller控制器實例(其可以或可以不被在範圍與「控制器作爲」語法曝光)。

thiscompile中的DDO對象(因此this在此處是上下文相關的)。

thisundefined鏈接功能(嚴格模式)。

link = (...) => { ... }; 
+0

謝謝你,很好的解釋。在http://stackoverflow.com/questions/34561415/why-is-this-null-in-the-link-function-within-an-angular-directive解決方案的作品,但現在我明白了爲什麼它的作品。 – wwarby

0

// TSC寫入 「變種_this =此;」在這裏,但是這是不明確的

可能存在兩個問題:

  • 你應該在調試控制檯中輸入_this。這是因爲Sourcemaps目前的工作方式:Chrome Typescript debugging references wrong 'this'

  • 您正在以錯誤的方式向angular註冊指令。請注意,如果使用像.directive('foo',foo)那樣的foo,角度將不會在foo上調用新的。 Angular假設它已經是一個擁有所有正確內容的變量。 Angular並不是以類爲基礎編寫的(角1現在相當古老)。

相關問題