Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

もうすぐリリースされるAngularJS 1.4の機能を先取りチェックしよう

AngularJSで初めるJavaScriptフレームワーク開発スタイル 第9回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/05/27 14:00

 AngularJSではもうすぐバージョン1.4がリリースされます。1.4へのバージョンアップでは新しい機能が追加されると共に、便利な機能アップはもちろん、パフォーマンスの向上や、そして残念ながら、これまで通りの利用方法が使えなくなってしまう部分も少々あります。今回は、AngularJSの利用者向けに、新機能や注意すべきポイントなどを紹介します。

目次

対象読者

  • AngularJSを使っている開発者
  • JavaScriptのフレームワークの動向などに興味を持っている方

必要な環境

 この記事では、AngularJSを使用し、Chrome(42.0)、IE11、Firefox(37.0)、Safari(8.0.4)の環境にて確認を行っています。

バージョン1.4では何がかわるのか

 バージョン1.4での大きな特徴として、以下の変更がある予定です。

  • 新しいRouter機能(ngNewRouter)
  • より柔軟なクッキー機能($cookies)
  • $parseや$compileのパフォーマンス改善
  • $httpサービスにおけるパラメータシリアライズ方式の柔軟性強化
  • ICU MessageFormatに対応したAngularJS式の利用

 基本的には過去のソースコードが動かなくなるような変更はあまりなく、内部ハックをしているような開発者を除けば、既存のソースコードの対応が必要になってしまうケースは非常に限定的だと思います。

 これら以外にも、細かい変更が多数含まれていて、実際に利用しているとちょっとした変更で便利になる機能や、ちょっと困ってしまう部分に対しての改善が随所に見られます。ただし、ngNewRouterはまだまだ仕様変更などがありそうですので、それ以外の新機能や機能改善の中で今回筆者が注目したものをいくつか紹介していきます。

新しい機能

 バージョン1.4で新たに追加される機能を紹介します。

$http - パラメータのシリアライズ方法をカスタマイズする

 $httpサービスでは、新たにGETパラメータを簡単にカスタマイズできるようになりました。また、ビルトインで利用できるシリアライズを提供する、以下の2つのサービスが追加されました。

  • $httpParamSerializer - $httpサービスの中で、デフォルトで使用されているシリアライザ
  • $httpParamSerializerJQLike - jQueryと同様のシリアライズ方法を提供するシリアライザ

 例えば、jQueryのajax(get/post)メソッドでは、配列データの場合には「[]」付きでパラメータを作成しますが、そのような変更もリスト1のように簡単に変更が可能です。

リスト1 $httpでの新しいシリアライザの利用(http/app.jsの抜粋)
var module = angular.module('app', []);
module.controller('AppController', ['$http','$httpParamSerializerJQLike',AppController]);
// (1) jQueryと同じようなkey[]=value1&key[]=valueのような形式にする
function AppController($http,$httpParamSerializerJQLike) {
  $http({
    method: 'GET',
    url: 'request.php',
    paramSerializer: $httpParamSerializerJQLike,  // (2) シリアライズ方法を指定する
    params: {
      key: ['value1', 'value2'],
      foo: 'hoge'
    }
  }).success(function(result) {
    // : 省略
  });

  // (3) 自分で自由な形式にすることも可能
  $http({
    method: 'GET',
    url: 'request.php',
    paramSerializer: function(params) {
      var arr = [];
      for(var name in params) {
        if(angular.isArray(params[name])) {
          arr.push(name + "!" + params[name].join(','));
        }
        else {
          arr.push(name + "!" + params[name]);
        }
      }
      return arr.join("/");
    },
    params: {
      key1: ['value1', 'value2'],
      foo: 'hoge'
    }
  }).success(function(result) {
    // : 省略
  });

  //  (4) POSTデータのシリアライズに使う
  $http({
    method: 'POST',
    url: 'request.php',
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
    transformRequest: $httpParamSerializerJQLike,
    data: {
      key1: ['value1', 'value2'],
      foo: 'hoge'
    }
  }).success(function(result) {
    // : 省略
  });
}

 (1)は、jQueryと同様にシリアライズを行うためのコードです。シリアライズ方法を変更するためには(2)のようにparamSerializerに指定します。(3)のように自分で好きなようにシリアライズ方法を変更するともできます。

 また、このシリアライズサービスはGETパラメータ以外にも利用できます。例えば、(4)のように、POST時にJSONではなくFORMを利用した、POSTと同じような動作をさせる場合にはtransformRequestに指定することもできます。

ngJq - 内部で使用するjQuery互換モジュールの指定をする

 AngularJSはjQueryが必須ではなく、jQueryがない場合にはjQueryのサブセットであるjqLiteを使い、jQueryが存在している場合にはjQueryを使っていました。ngJqディレクティブによりこれらの指定が自由にできるようになりました。リスト2のように、jQueryの指定があってもHTML要素にng-jq属性の指定がある場合にはjQueryを使わず、jqLiteを使います。

リスト2 ngJqでjqLiteを必ず使うときの使用例(jq/index.htmlの抜粋)
<html ng-jq>
<head>
    <script src="http://code.jquery.com/jquery-2.1.3.js"></script>
    <script src="../vendors/1_4/angular.js"></script>
</head>

 また、リスト3のようにng-jqに値を指定することで異なるjQueryのバージョンの中から特定のバージョンを利用するもできます。

リスト3 ngJqでjQueryの特定のバージョンを使うときの使用例(jq/jquery.htmlの抜粋)
<!DOCTYPE html>
<html ng-jq="jq1">
<head>
    :  省略
    <script src="https://code.jquery.com/jquery-1.11.2.js"></script> <!-- (1) 1.11.2のバージョンを指定 -->
    <script>
        var jq1 = jQuery.noConflict(); <-- (2) ng-jqで指定した値と同じ変数名を利用 -->
    </script>
    <script src="http://code.jquery.com/jquery-2.1.3.js"></script> <!-- (3)他のライブラリでは2.1.3を利用-->
    :  省略
</head>

 (1)でまず、AngularJS内で使用するjQueryを読み込み、(2)でjQueryのnoConflictメソッドを用いて「$」ではなくng-jqにて指定した変数名である「jq1」オブジェクトを作成します。

 (3)では、AngularJS以外で利用するjQueryを読み込みます。

limitToフィルタ - オプションの追加によりページング処理を簡単に実現する

 バージョン1.3までは、limitToフィルタを使えば配列内にあるデータから最初の指定件数だけを出力することができました。バージョン1.4では、ここに取得するデータの始まりのインデックスが指定できるようになります。

 フィルタはngRepeatと共に利用することもできるため、なぜこのオプションがなかったのかが不思議なくらいですが、これでやっとページング処理が、リスト4のようにlimitToとngRepeatだけを使って実現できるようになりました。

リスト4 limitToフィルタを使ったページングをするためのHTML(limitTo/index.htmlの抜粋)
<body ng-app="app" ng-controller="LimitToController">
    <!-- (1) 単純な使い方 -->
    <div >{{list | limitTo: 3: 3}}</div>

    <h5>ページング</h5>
    <!-- (2) ngRepeatと組み合わせることで簡単にページング処理ができるようになる -->
    <div>
        <a ng-click="page(0)">1ページ</a>|
        <a ng-click="page(1)">2ページ</a>|
        <a ng-click="page(2)">3ページ</a>|
        <a ng-click="page(3)">4ページ</a>
    </div>
    <div ng-repeat="item in list | limitTo: limit: begin" style="border-bottom: 1px solid #666">
        <span>{{item}}</span>
    </div>
</body>

 (1)は最も基本的なlimitToのフィルタの使用例です。続いて(2)のようにngRepeatと組み合わせて使用するとページング処理を作成することができます。

図1 limitToのサンプルコードの実行結果
図1 limitToのサンプルコードの実行結果

 また、リスト5は実際のデータを作成する部分や、ページの切替を行うためのコントローラの実装例です。

リスト5 ページングをするためのコントローラ例(limitTo/app.jsの抜粋)
module.controller('LimitToController',['$scope',function($scope){
  var list = [];
  for(var i = 0; i < 20; i++){
    list.push(i);
  }
  $scope.list = list;  // データ
  $scope.limit = 5;   // 1ページ当たりの件数
  $scope.begin = 0;  // 現在のページの最初のindex
  $scope.page = function(page){
    $scope.begin = page * $scope.limit;
  }
}]);

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2017年5月時点での登録メンバは52名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:AngularJSではじめるJavaScriptフレームワーク開発スタイル

もっと読む

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5