網站搜尋

在 Typescript 中將 angularjs 指令實現為類別


所以在查看了一些 TypeScript 中 AngularJS 指令的範例之後,似乎大多數人都同意在實作它們時使用函數而不是類別。

我更希望將它們作為一個類別,並嘗試按以下方式實現它們:

module directives
{    
    export class search implements ng.IDirective
    {        
        public restrict: string;
        public templateUrl: string;

        constructor()
        {            
            this.restrict = 'AE';
            this.templateUrl = 'directives/search.html';
        }

        public link($scope: ng.IScope, element: JQuery, attributes: ng.IAttributes)
        {
            element.text("Hello world");

        }
    }
} 

現在這個運作良好。然而,我需要有一個帶有一些屬性的獨立作用域,而我一直在努力找出如何將其包含在類本身中。

邏輯推理表明,既然我可以擁有

public restrict: string;
public templateUrl: string;

我應該能夠擁有像這樣的東西:

public scope;

但我不確定這是否正確,也不知道該如何從那裡繼續(例如如何將屬性添加到範圍中)。

有人知道怎麼解這個嗎?(希望,如果可能的話,不用回退到函數)

謝謝,

答案#1

將指令創建為類可能會有問題,因為你仍然需要使用工廠函數來包裝其實例化。例如:

export class SomeDirective implements ng.IDirective {
    public link = () => {
    }

    constructor() {}
}

無效的方法

myModule.directive('someDirective', SomeDirective);

由於指令不是使用 'new' 調用的,而是直接作為工廠函數調用的。這將會對你的構造函數實際返回的內容造成問題。

含有警告的意思是什麼

myModule.directive(() => new SomeDirective());

這在沒有涉及任何 IoC 的情況下運作良好,但一旦你開始引入可注入的項目,你就必須為你的工廠函數和指令構造函數維護重複的參數列表。

export class SomeDirective implements ng.IDirective {
    ...
    constructor(someService: any) {}
}

myModule.directive('someDirective', ['someService', (someService) => new SomeDirective(someService)]);

如果你喜歡,那仍然是一個選擇,但重要的是要了解指令註冊實際上是如何被使用的。

另一種方法

Angular 實際上期望的是一個指令工廠函數,所以應該是像這樣的東西:

export var SomeDirectiveFactory = (someService: any): ng.IDirective => {
   return {
     link: () => {...}
   };
}
SomeDirectiveFactory.$inject = ['someService']; //including $inject annotations

myModule.directive('someDirective', SomeDirectiveFactory);

這樣做的好處是可以使用 $inject 註解,因為在這種情況下 Angular 需要它在工廠函數上。

你也可以總是從工廠函數返回你類的實例:

export var SomeDirectiveFactory = (someService: any): ng.IDirective => {
   return new SomeDirective(someService);
}
SomeDirectiveFactory.$inject = ['someService']; //including $inject annotations

但這真的取決於你的使用情況,你能接受多少參數列表的重複,等等。

答案#2

假設你現有的可以在沒有隔離範圍的情況下運作,以下應該可以在隔離範圍下運作:

module directives
{    
    export class search implements ng.IDirective
    {        
        public restrict = 'AE';
        public templateUrl = 'directives/search.html';
        public scope = {
            foo:'=',
            bar:'@',
            bas:'&'
        };


        public link($scope: ng.IScope, element: JQuery, attributes: ng.IAttributes)
        {
            element.text("Hello world");
        }
    }
}