LoginSignup
0
1

More than 5 years have passed since last update.

TypeScriptでカスタムdirectiveのpre/postLinkの書き方

Posted at

最初に

世間はAngular2で盛り上がっているのにlinkの話かーいって感じですが、directive内でDOM操作したい、jQuery使いたいとかまだニーズあるよね、ということで実装してみました。

調べ方も含めてご参考までに…。

やりたいことは、AngularJS Directiveの処理順を網羅してみた:処理中にjQueryで要素を追加したらどーなるのの、k-cパターンです。

k-c: pre-link内でjQuery#append()

version

  • Angular 1.5
  • TypeScript 1.8

定義ファイルを読む

interface IDirective

angular.d.ts
interface IDirective {
    compile?: IDirectiveCompileFn;
    controller?: any;
    controllerAs?: string;
    /**
     * @deprecated
     * Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before
     * the controller constructor is called, this use is now deprecated. Please place initialization code that
     * relies upon bindings inside a $onInit method on the controller, instead.
     */
    bindToController?: boolean | Object;
    link?: IDirectiveLinkFn | IDirectivePrePost;
    multiElement?: boolean;
    name?: string;
    priority?: number;
    /**
     * @deprecated
     */
    replace?: boolean;
    require?: string | string[] | {[controller: string]: string};
    restrict?: string;
    scope?: boolean | Object;
    template?: string | Function;
    templateNamespace?: string;
    templateUrl?: string | Function;
    terminal?: boolean;
    transclude?: boolean | string | {[slot: string]: string};
}

link?: IDirectiveLinkFn | IDirectivePrePost;となっているので、linkにはIDirectiveLinkFn かIDirectivePrePostのInterfaceを使えばいいみたいです。

interface IDirectiveLinkFn / IDirectivePrePost

angular.d.ts
interface IDirectiveLinkFn {
    (
        scope: IScope,
        instanceElement: IAugmentedJQuery,
        instanceAttributes: IAttributes,
        controller: {},
        transclude: ITranscludeFunction
    ): void;
}

interface IDirectivePrePost {
    pre?: IDirectiveLinkFn;
    post?: IDirectiveLinkFn;
}

IDirectivePrePostでpre/postにそれぞれIDirectiveLinkFnを継承していますね。
というわけで、IDirectiveを継承したカスタムdirectiveにIDirectivePrePostを継承させたlinkを作成しましょう。

蛇足:interface IDirectiveCompileFn

angular.d.ts
interface IDirectiveCompileFn {
        (
            templateElement: IAugmentedJQuery,
            templateAttributes: IAttributes,
            /**
             * @deprecated
             * Note: The transclude function that is passed to the compile function is deprecated,
             * as it e.g. does not know about the right outer scope. Please use the transclude function
             * that is passed to the link function instead.
             */
            transclude: ITranscludeFunction
        ): IDirectivePrePost;
    }

IDirectiveCompileFnはIDirectivePrePostを返しています。

書いてみた

myDirective.ts
module myDirectivesModule {

    export class myDirective implements ng.IDirective{
        // TODO IDirectiveを参考に必要なものを定義
        // public restrict: string;
        // public …

        constructor() {
           this.init();
        }

        public static Factory(): ng.IDirectiveFactory {
            "ngInject";
            var directive = () => {
                return new myDirective();
            }
            return directive;
        }

        // ここ!!
        public link: ng.IDirectivePrePost = {
            pre: ($scope: ng.IScope, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes): void => {
                // prelinkで実行したい処理
            },
            post: ($scope: ng.IScope, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes): void => {
                // postlinkで実行したい処理
            }
        }

        private init() {
            // TODO 初期化
            // this.restrict = 'E';
            // this.…
        }
    }   
}

var myapp = angular.module("app"); //ng-app="app"
"ngInject";
myapp.directive('myCustomDirective', myDirectivesModule.myDirective.Factory());
sample.html
<html lang="ja" ng-app="app">
//・・・
 <my-custom-directive></my-custom-directive>
//・・・
</html>
  • "ngInject";:gulp-ng-annotate用の定義です。

感想

TypeScriptは定義ファイルみたら何とかなるー…かもヽ( ´ ∇ ` )ノ

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1