AngularJS TypeScript 指令链接函数
Posted
技术标签:
【中文标题】AngularJS TypeScript 指令链接函数【英文标题】:AngularJS TypeScript directive link function 【发布时间】:2014-07-05 20:15:14 【问题描述】:我正在尝试使用 TypeScript 创建一个 AngularJS 指令。我的指令需要“ngModel”,并且我还使用了在我的指令中注入的自定义服务。 我的主要问题是我的服务不能在我的链接函数中使用。
这是我想要实现的一个示例:
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”这一事实对我来说没有多大意义。任何想法为什么会这样?
【问题讨论】:
【参考方案1】:使用类并从 ng.IDirective 继承是 TypeScript 的方式。
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://***.com/a/29223535/990356
【讨论】:
这个 IMyDirectiveScope 类型在哪里定义?而对于 app.services.MyFactory 它的定义是什么? @Oscar 你应该先阅读这个问题:interface IMyDirectiveScope extends ng.IScope
我们可以在不使用链接功能的情况下实现这一点吗?我正在使用 Angular 1.4,由于我们将代码转换为 Angular 2.0 并且那里不支持链接函数,所以我不想使用链接函数编写此逻辑。所以请告诉我是否可以在没有的情况下访问该元素链接函数。
这实际上并不完全有效。您是否尝试过在一个父控制器下添加两个相同的指令?查看变量的作用域,您会注意到两个指令的作用域都是最后一个指令隔离作用域,行为不正确。【参考方案2】:
类非常适合控制器和指令控制器,但我不认为我会为整个指令使用一个。但如果你愿意,你可能不得不做这样的事情:
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();
);
【讨论】:
谢谢这个作品,你能给我一个例子,你将如何在没有课程的情况下处理这种情况? @user1613512 我编辑了我的答案以包含一个没有类的示例 写 unboundLink(...) var self = this; ... 然后你可以在 validate() 中使用 self 变量而不是 this。以上是关于AngularJS TypeScript 指令链接函数的主要内容,如果未能解决你的问题,请参考以下文章
带有 ControllerAs 和 TypeScript 类的 AngularJs 指令
如何使用 TypeScript 解决 AngularJS 指令
Angularjs+Typescript 指令实现 $compile
在 Typescript 中将 angularjs 指令实现为类