AngularJS类型脚本指令

AngularJS类型脚本指令,angularjs,typescript,directive,Angularjs,Typescript,Directive,使用Typescript创建嵌套指令时出现问题。我可以用简单的AngularJs来做: , 但是使用TypeScript它会给我“无控制器”错误消息 /// <reference path="../../Scripts/AngularJs/Typings/angular.d.ts" /> export class directiveA { public static $inject: Array<string> = []; constructor() {

使用Typescript创建嵌套指令时出现问题。我可以用简单的AngularJs来做: ,

但是使用TypeScript它会给我“无控制器”错误消息

/// <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;
    }
}
//
导出类指令a{
公共静态$inject:Array=[];
构造函数(){
var指令:ng.IDirective={};
指令优先级=0;
指令.restrict=“A”;
directive.scope={};
directive.transclude=true;
directive.templateUrl=“otherTemplate.html”;
directive.replace=true;
directive.controller=函数($scope,$element){
this.flip=函数(){
$element.toggleClass(“翻转”);
}
}
directive.replace=true;
返回指令;
}
} 
导出类指令B{
公共静态$inject:Array=[];
构造函数(){
var指令:ng.IDirective={};
directive.require=“^directiveA”;
指令优先级=1;
指令.restrict=“A”;
指令范围={
SimplSide:“@”
};
directive.transclude=true;
directive.templateUrl=“templateUrl.html”;
directive.link=函数(范围、IELENT、iAttrs、SimpledTable){
scope.flip=函数(){
simpleditable.flip();
}
}
directive.replace=true;
返回指令;
}
}

我不知道它是否相关,但我使用AMD Require.JS进行脚本加载

假设您将这些注册为:

import mod = require('yourfile')
youmodule.directive('directiveA',mod.directiveA);
youmodule.directive('directiveB',mod.directiveB);
只要您的html看起来像:

<div directiveA>
  <div directiveB>
  </div>
</div>
它编译为不正确的javascript。由于调用函数测试时没有使用新运算符,这意味着
引用的是
窗口
,而不是类的实例。因此,无论如何,您不能使用构造函数之外定义的任何内容。我推荐如下:

class Test{
    foo = "EAC";
    constructor(){
        var directive:any = {}; 
        directive.restrict = this.foo;
    }
} 
function foo():ng.IDirective{
    return {
        restrict: 'EAC';    
    }
}
这样,typescript将帮助您为angular编写正确的javascript,而不是以错误的方式指向您。我会在某个时候制作一个视频

为控制器使用类 指令内部的控制器也使用新运算符调用。与外部控制器相同:再次让typescript在控制器定义中帮助您理解
的含义。此外,您还可以在child指令中使用控制器的类型,例如(用于类型安全性和推断):

用于注入指令功能 我仍然使用$inject。我有以下接口定义:

interface Function{
    $inject:string[]
}
这意味着您可以:

foo.$inject = ['$compile']; // e.g

这个问题与Typescript无关,而是与AngularJS指令有关。 将templateUrl更改为template并使用内联代码有助于解决错误。这是AngularJS的问题,更多信息: 希望他们将来能解决这个问题

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;
    }
} 
导出类指令a{
公共静态$inject:Array=[];
构造函数(){
var指令:ng.IDirective={};
指令优先级=0;
指令.restrict=“A”;
directive.scope={};
directive.transclude=true;
directive.template=“您的内容”;
directive.replace=true;
directive.controller=函数($scope,$element){
this.flip=函数(){
//一些函数
}
}
directive.replace=true;
返回指令;
}
} 

在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>
D类{
静态foo(){
返回{
限制:'A',
模板:'我来拯救这一天',
替换:正确
}
}
}
/// 
/// 
类MyApp{
公共应用程序:AngularModule;
构造函数(){
this.app=angular.module('myApp',[]);
this.app.directive('superman',()=>{
返回D.foo();
} 
);
}
}
新MyApp();
指示

使用我的解决方案,您既可以使用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):



我使用指令的方式允许我使用注入,并且我在调用函数时返回一个对象,因此将其放入函数中,会使我将可注入项注入到我定义指令的其他地方。如果页面内容是从缓存中获取的,则此解决方案仍然有效。添加了关于注入函数的注释:)注册指令时,字符串标识符的第一个字母必须是小写。这让我陷入了一点思考,我可以遵循C#约定,希望它能帮助别人。@parliament在html中遵循js约定;)。PS理由:html不区分大小写=>指令'fooBar'用作'fooBar',因此'foo'不可用,因为'-foo'本身就很奇怪,我假设您正在注册它们。请参阅我的更新答案:)如何向角度模块添加以这种方式声明的指令?
this.app.directive(“myDirective”,()=>newdirectivea())
此示例适用于
$location
,但不适用于
$scope
。我得到了一个
未知的提供程序:$scopeProvider要解决这个问题,我在指令模块中注册了我的控制器,并在指令中指定了
控制器:'MyDirectiveController'
angular.module('common', [])
    .directive('searchInput', YourApp.Common.Directives.SearchInputDirective);
<form ng-submit="SearchInputController.doSearch()">
    <input type="search" ng-model="SearchInputController.query">
</form>