AngularJS 打字稿指令
Posted
技术标签:
【中文标题】AngularJS 打字稿指令【英文标题】:AngularJS Typescript Directive 【发布时间】:2013-07-30 10:42:25 【问题描述】:使用 Typescript 创建嵌套指令时遇到问题。我可以用简单的 AngularJs 做到这一点: http://plnkr.co/edit/UruTqEdMnqNT5wjxcQNC?p=preview,
但使用 TypeScript 它给了我 “No controller” 错误消息。
/// <reference path="../../Scripts/AngularJs/Typings/angular.d.ts" />
export class directiveA
public static $inject: Array<string> = [];
constructor()
var directive: ng.IDirective = ;
directive.priority = 0;
directive.restrict = "A";
directive.scope = ;
directive.transclude = true;
directive.templateUrl = "otherTemplate.html";
directive.replace = true;
directive.controller = function ($scope, $element)
this.flip = function ()
$element.toggleClass("flipped");
directive.replace = true;
return directive;
export class directiveB
public static $inject: Array<string> = [];
constructor()
var directive: ng.IDirective = ;
directive.require = "^directiveA";
directive.priority = 1;
directive.restrict = "A";
directive.scope =
simplrSide : "@"
;
directive.transclude = true;
directive.templateUrl = "templeUrl.html";
directive.link = function (scope, iElement, iAttrs, simplrEditable)
scope.flip = function ()
simplrEditable.flip();
directive.replace = true;
return directive;
我不知道它是否相关,但我正在使用 AMD Require.JS 进行脚本加载
【问题讨论】:
我假设您正在注册这些。查看我的更新答案:) 【参考方案1】:假设您将这些注册为:
import mod = require('yourfile')
youmodule.directive('directiveA',mod.directiveA);
youmodule.directive('directiveB',mod.directiveB);
只要您的 html 看起来像这样,这应该可以工作:
<div directiveA>
<div directiveB>
</div>
</div>
除此之外还有几点注意事项:
为指令定义使用函数。
这是因为指令(与控制器不同)是在没有new
运算符的情况下调用的。所以如果你有类似的东西:
class Test
foo = "EAC";
constructor()
var directive:any = ;
directive.restrict = this.foo;
它编译成不正确 javascript。由于函数 Test 是在没有 new 运算符的情况下调用的,这意味着 this
指的是 window
而不是类的实例。所以无论如何你都不能使用在构造函数之外定义的任何东西。我推荐类似的东西:
function foo():ng.IDirective
return
restrict: 'EAC';
这种方式打字稿将帮助您为 Angular 编写正确的 javascript,而不是以错误的方式指出您。 我会在某个时候制作一个关于这个的视频
为您的控制器使用类
指令中的控制器也使用 new 运算符调用。与外部控制器相同:http://www.youtube.com/watch?v=WdtVn_8K17E 再次让 typescript 帮助您了解控制器定义中 this
的含义。另外,您可以在子指令中将 type 用于控制器,例如(用于类型安全和推理):
link: function (scope, iElement, iAttrs, simplrEditable:YourControllerClass)
用于注入指令函数 我仍然使用 $inject。我有以下接口定义:
interface Function
$inject:string[]
这意味着你可以这样做:
foo.$inject = ['$compile']; // e.g
【讨论】:
我使用指令的方式让我可以使用注入,并且在调用函数时返回一个对象,因此将其放入函数中会使我在其他地方注入 Injectables,我在其中定义指令.如果页面内容是从缓存中获取的,那么这个解决方案仍然有效。 添加了关于注入函数的注释:) 注册指令时,字符串标识符的首字母必须小写。这让我有点想我可以遵循 C# 约定,希望它对某人有所帮助。 @parliament 在 html 中遵循 js 约定;)。 PS 原因:html 不区分大小写 => 指令 'fooBar' 用作 'foo-bar',因此 'Foo' 不可用,因为 '-foo' 本身很奇怪【参考方案2】:该问题与 Typescript 无关,而与 AngularJS 指令有关。 将 templateUrl 更改为 template 并使用内联代码有助于解决错误。这是 AngularJS 问题,更多内容:https://github.com/angular/angular.js/issues/1903 希望他们将来能解决这个问题!
export class directiveA
public static $inject: Array<string> = [];
constructor()
var directive: ng.IDirective = ;
directive.priority = 0;
directive.restrict = "A";
directive.scope = ;
directive.transclude = true;
directive.template = "<div>Your content</div>";
directive.replace = true;
directive.controller = function ($scope, $element)
this.flip = function ()
//Some func
directive.replace = true;
return directive;
【讨论】:
如何将这样声明的指令添加到 Angular 模块中?this.app.directive("myDirective", () => new directiveA());
【参考方案3】:
使用我的解决方案,您既可以使用 TS 类,又不必担心工厂并重复您需要注入的内容。
module YourApp.Common.Directives
class SearchInputController
public query: string;
constructor(private $location: ng.ILocationService)
doSearch(): void
this.$location.url(`/search?q=$this.query`);
this.query = '';
export function SearchInputDirective($location: ng.ILocationService): ng.IDirective
return
restrict: 'E',
templateUrl: 'common/directives/searchInput/SearchInputDirective.html',
replace: true,
scope: true,
controllerAs: 'SearchInputController',
bindToController:
'query': '@'
,
controller: (): any => new SearchInputController($location)
;
SearchInputDirective.$inject = ['$location'];
注册:
angular.module('common', [])
.directive('searchInput', YourApp.Common.Directives.SearchInputDirective);
和HTML看全图(templateUrl):
<form ng-submit="SearchInputController.doSearch()">
<input type="search" ng-model="SearchInputController.query">
</form>
【讨论】:
此示例适用于$location
,但适用于$scope
。我收到了Unknown provider: $scopeProvider <- $scope <- myDirective
为了解决这个问题,我在我的指令模块中注册了我的控制器并在我的指令中指定了controller: 'MyDirectiveController'
。
其实这里是an even better method(向下滚动到directives/to-do-list.ts)【参考方案4】:
在ts中编写指令的简单方法 我认为也可以使用嵌套指令
class D
static foo()
return
restrict:'A',
template:'<div>Here I am to save the day</div>',
replace: true
/// <reference path="./angular.d.ts"/>
/// <reference path="./directive.ts"/>
class MyApp
public app:AngularModule;
constructor()
this.app = angular.module('myApp', []);
this.app.directive ('superman',() =>
return D.foo();
);
new MyApp();
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Directive</title>
</head>
<body>
<div data-ng-app="myApp">
<div data-superman></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="./directive.js"></script>
<script src="./appDirective.js"></script>
</body>
</html>
【讨论】:
以上是关于AngularJS 打字稿指令的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot、maven、AngularJS 2、打字稿和实时重载