8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularJSのcomponentをTypeScriptで実装してみる

Posted at

はじめに

 AngularJSの1.5.xより component が実装され、巷の噂ではAngularJSはTypeScriptを相性が良いとのことで、実装方法を研究したメモを残す。

開発環境

  • VisualStudio 2015
  • プロジェクトのプロパティの「TypeScriptビルド」の「出力」項目、「Javascript 出力をファイルに統合する」にチェックを入れ、値を「application.js」にする
  • NuGetで、以下のパッケージを読み込む
  1. es6-promise.TypeScript.DefinitelyTyped (v0.1.3)
  2. angularjs.TypeScript.DefinitelyTyped (v5.4.2)
  3. jquery.TypeScript.DefinitelyTyped (v3.0.4)

Viewの実装

単純にcomponentで作成されたタグを表示する

index.html
<!DOCTYPE html>
<html lang="ja" ng-app="app">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>

    <script src="application.js"></script>
</head>
<body ng-controller="MainController as main">
    <h1 ng-bind="main.title"></h1>
    <element-test param-title="main.subTitle" call-back-event="main.callback1(value)"></element-test>
</body>
</html>

element-testの仕様

  1. param-title : element-testの中で表示するタイトル
  2. call-back-event : コントローラ側のイベントを呼び出す

モジュール定義

angularのappを定義します

app.ts
/// <reference path="_include.ts" />
module app {
    var module = angular.module('app', []);
    module.controller('MainController', MainController);
    module.component('elementTest', ElementComponentFactory());
}
_include.ts
/// <reference path="scripts/typings/jquery/jquery.d.ts" />
/// <reference path="scripts/typings/angularjs/angular.d.ts" />
/// <reference path="scripts/typings/es6-promise/es6-promise.d.ts" />

/// <reference path="main.controller.ts" />
/// <reference path="element.component.ts" />

メインコントローラ

main.controller.ts
/// <reference path="_include.ts" />
module app {
    /**
     * メイン コントローラ
     */
    export class MainController {
        // タイトル
        title: string;
        // サブタイトル
        subTitle: string;
        // コールバック
        callback1: Function;
        /**
         * コンストラクタ
         */
        constructor() {
            this.title = "AngularJS(1.5)でcomponent実装";

            this.subTitle = "コントローラから設定したパラメタ";

            // コールバックの設定
            this.callback1 = (value : any) => {
                // コールバックが呼び出される。valueは「1001」
            }
        }
    }
}

コンポーネント

element.component.ts
/// <reference path="_include.ts" />
module app {
    /**
     * Element コンポーネント作成
     */
    export function ElementComponentFactory(): ng.IComponentOptions {
        return {
            bindings:
            {
                //コントローラパラメタ
                paramTitle: '=',
                //コールバック
                callBackEvent: '&'
            },

            template: [
                    "<div>",
                    "<p ng-bind='_my.displayItem'></p>",
                    "<button ng-click='_my.clickButton(123)'>ボタン</button>",
                    "</div>"
                ].join(""),
            controllerAs: '_my',
            controller: ElementComponent
        };
    }
    /**
     * コントローラ
     * @returns
     */
    class ElementComponent {
        public static $inject = ['$http'];  // httpサービスの注入

        /**
         * 表示項目
         */
        displayItem: string;
        /**
         * コールバック
         */
        callBackEvent: Function;

        // タイトル
        private _paramTitle: string;  
        get paramTitle (): string {
            return this._paramTitle;
        }
        /**
         * コントローラとのI/O
         * @param {string} value
         */
        set paramTitle(value: string) {
            if (!angular.isDefined(value)) {
                return;
            }
            this._paramTitle = value;
            // パラメタが設定された処理
            this.displayItem = value;
        } 
        /**
         * コンストラクタ
         * @param {ng.IHttpService} public $http
         */
        constructor(public $http: ng.IHttpService) {
            // this.$http で httpサービスが使用可能
        }
        /**
         * ボタンが押された
         * @param {number} value 値
         */
        clickButton(value: number): void {
            // valueは「123」が設定されている
            this.callBackEvent({ 'value': 1001 });
            this.paramTitle = "ボタン押下";
        }
    }
}

ポイント

  • component の controller は class で実装する
  • 従来 $scope 経由で操作していたプロパティ類は、controller class のプロパティで宣言する
  • コントローラからの値受信は、 setter の中で処理を行う
  • コントローラへの callback は Function型 で定義したプロパティを呼び出す

最後に

自分は、Javascriptと言う言語が気持ち悪くて、コード実装時はモチベーションが事が下がったままでしたが、TypeScriptの場合は綺麗なコードになり、書いてて楽しくなりました。

8
9
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
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?