2014-05-17 51 views
15

我正在尝试使用TypeScript创建一个AngularJS指令。我的指令需要'ngModel',我也使用了我的指令中注入的自定义服务。 我的主要问题是我的服务无法在我的链接功能中使用。AngularJS TypeScript指令链接功能

这里是我想要达到一个例子:

module app.directives { 

    export var directiveName: string = "theDirective"; 

    angular.module("myApp").directive(directiveName, 
      (myFactory: app.services.MyFactory) => 
      { 
       return new MyDirective(myFactory); 
      }); 

    export interface IMyDirectiveScope extends ng.IScope { 
     ngModel: ng.INgModelController; 
    } 

    export class MyDirective implements ng.IDirective { 

     restrict = "A"; 
     require = "ngModel"; 
     scope = { 
      ngModel:'=' 
     } 

     constructor(private myFactory: app.services.MyFactory) { 

     } 


     link(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
      //this is window here 

      elem.bind('blur', (evt: JQueryEventObject) => { 
       //keyword this is also window here, so yeah bummer indeed 
       validate(); 
      }); 

      function validate() { 
       //I need to use my factory here, but I can seem to get it. 
       //this is always window and I'm kinda stuck here 
      } 
     } 
    } 
} 

我似乎无法找到有关这个主题的一些更高级的东西。所有的例子我都不觉得似乎没有使用服务或复杂的链接功能。 请用某种例子回答这个问题。你认为这是骗人的。

更新:在我的链接函数中的'this'是窗口而不是'MyDirective'的事实对我来说没有多大意义。任何想法为什么会这样?

回答

16

类适用于控制器和指令控制器,但我不认为我会使用整个指令。但是,如果你想你可能不得不做这样的事情:

export class MyDirective implements ng.IDirective { 

    public link; 

    restrict = "A"; 
    require = "ngModel"; 
    scope = { 
     ngModel:'=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
     this.link = this.unboundLink.bind(this); 
    } 


    unboundLink(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
     //Now you should be able to access myFactory 
     this.myFactory.doSomething(); 

     elem.bind('blur', (evt: JQueryEventObject) => { 
      //keyword this is also window here, so yeah bummer indeed 
      validate(); 
     }); 

     function validate() { 
      //I need to use my factory here, but I can seem to get it. 
      //this is always window and I'm kinda stuck here 
     } 
    } 
} 

编辑:没有一类,你可以做这样的事情:

angular.module("myApp").directive("theDirective", 
    function(myFactory: app.services.MyFactory) { 
     return { 
      restrict: 'A', 
      require: 'ngModel', 
      scope: {'ngModel': '='}, 
      link: function(scope: IMyDirectiveScope , elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) { 
       //You can access myFactory like this. 
       myFactory.doSomething(); 
      } 
     } 
    } 
); 
+0

钍这是有效的,你能举一个例子,你如何在没有课堂的情况下处理这种情况? – user1613512

+0

@ user1613512我编辑了我的答案,以包含一个没有类的例子 – rob

+0

Write unboundLink(...){var self = this; ...}那么你可以在validate()中使用self变量而不是这个。 –

21

使用类和ng.IDirective继承是使用TypeScript的方法。

打字稿包括来自EcmaScript的6 为脂肪箭头功能() =>支持这是一个速记语法也改变了this关键字的工作方式:

class MyDirective implements ng.IDirective { 
    restrict = 'A'; 
    require = 'ngModel'; 
    scope = { 
     ngModel: '=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
    } 

    link = (scope: IMyDirectiveScope, elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) => { 
     console.log(this); // this points to MyDirective instance instead of Window 

     elem.bind('blur', (evt: JQueryEventObject) => { 
      console.log(this); // this points to MyDirective instance instead of Window 
      this.validate(); 
     }); 
    } 

    validate() { 
     console.log(this); // this points to MyDirective instance instead of Window 
    } 


    static factory(): ng.IDirectiveFactory { 
     var directive = (myFactory: app.services.MyFactory) => new MyDirective(myFactory); 
     directive.$inject = ['myFactory']; 
     return directive; 
    } 
} 

app.directive('mydirective', MyDirective.factory()); 

您也可以依靠老式var self = this;模式:

class MyDirective implements ng.IDirective { 
    restrict = 'A'; 
    require = 'ngModel'; 
    scope = { 
     ngModel: '=' 
    } 

    constructor(private myFactory: app.services.MyFactory) { 
    } 

    link = (scope: IMyDirectiveScope, elem: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController) => { 
     console.log(this); // this points to MyDirective instance instead of Window 

     var self = this; 

     function validate() { 
      console.log(self); // self points to MyDirective instance 
     } 

     elem.bind('blur', function(evt: JQueryEventObject) { 
      console.log(self); // self points to MyDirective instance 
      validate(); 
     }); 
    } 
} 

相关答案:https://stackoverflow.com/a/29223535/990356

+0

IMyDirectiveScope类型在哪里定义?和app.services.MyFactory的定义是什么? – Oscar

+0

@Oscar你应该先阅读这个问题:'接口IMyDirectiveScope扩展ng.IScope' –

+0

我们可以在不使用链接函数的情况下实现这个吗?我正在使用Angular 1.4,因为我们将把我们的代码保存到Angular 2.0中,并且链接函数不受支持,我不想使用链接函数编写此逻辑。所以,请让我知道是否可以访问该元素,而无需链接功能。 – ATHER

相关问题