Help us understand the problem. What is going on with this article?

AngularJSの1.3から1.4へのバージョンアップ

More than 3 years have passed since last update.

@tsuchikazuです。半年ほど仕事でAngularと戯れています。

3/21に開催されたng-japanでは、あと1週間後ほどでリリースされるとアナウンスされていたAngular 1.4
あれから10週間ほど経った5/27。ついに、Angular1.4の安定版がリリースされました。

Developer Guide: Migrating from 1.3 to 1.4CHANGELOGから、Breaking Changeを中心に簡単にまとめましたので、公開します。

概要

Angular1.4では、主にngAnimateの大きなリファクタリングと、ngMessagesの機能改善、$cookiesへの新しいAPIが追加されました。

ngAnimateのリファクタリングは、今まで存在していたissueやバグフィックスと、より便利なアニメーションを提供するための新APIのために行われました。これまでJavascriptとCSSアニメーションは、同時に実行することができていましたが、1.4からはできなくなります。しかし、同じ効果を出すために$animateCssが新しく提供されました。$animateCssを使うことで、JavascriptからCSSアニメーションを扱うことができ、今までより柔軟なアニメーションを提供できます。

ngModule.animation('.slide-animation', ['$animateCss', function($animateCss) {
  return {
    enter: function(element, doneFn) {
      // this will trigger a `.ng-enter` and `.ng-enter-active` CSS animation
      var animation = $animateCss(element, {
        event: 'enter'
        // any other CSS-related properties
        //   addClass: 'some-class',
        //   removeClass: 'some-other-class',
        //   from: {},
        //   to: {}
      });

      // make sure to read the ngAnimate docs to understand how this works
      animation.start().done(doneFn);
    }
  }
}]);

ngMessagesは、エラーメッセージを動的に表示するための機能として、エラーメッセージの配列を受け取ることが出来るようになり、ng-repeatなどで自由に表示することができます。ng-message-expdirectiveも新しく提供されました。

<div ng-messages="myForm.myEmail.$error" role="alert">
  <div ng-message="required">You did not enter your email address</div>
  <div ng-repeat="errorMessage in errorMessages">
    <!-- use ng-message-exp for a message whose key is given by an expression -->
    <div ng-message-exp="errorMessage.type">{{ errorMessage.text }}</div>
  </div>
</div>

$cookiesは、$cookieStoreがdeprecatedになり、$cookiesに統合されました。また、pathやdomainを指定できるようになりました。

var id = $cookies.get('id');
$cookies.put('id', id);
var object = $cookies.getObject('objectKey');
$cookies.putObject(object);

$cookies.put('key','value', {
  path : '/',
  expires : new Date(2015,7,1)
  secure : false,
  domain : 'tsuchikazu.net'
});

パフォーマンス面では、digest timeが最大30%、メモリ使用量は2%〜4%改善されています。その他、ngRepeatngOptions$httpfilterなどで細かな変更が入っていますが、大きな変更はないため1.3から1.4へは簡単にmigrationできるでしょう。

では、細かいBreaking Changeを紹介します。

Breaking Change

Animation

c8700f0によって、animationに関するcallbackに$animateを使うようになります。

// < 1.4
element.on('$animate:before', function(e, data) {
  if (data.event === 'enter') { ... }
});
element.off('$animate:before', fn);

// 1.4+
$animate.on(element, 'enter', function(data) {
  //...
});
$animate.off(element, 'enter', fn);

c8700f0によって、$animate.enabled()の引数の順番が変わります。

// < 1.4
$animate.enabled(false, element);

// 1.4+
$animate.enabled(element, false);

c8700f0によって、 $animate.enabled(element, false)した際に子要素のanimationがdisabledになっていましたが、自要素もdisabledになります。

c8700f0によって、animation promiseのthenの中で$scope.apply$scope.$digestをする必要がなくなります。

// < 1.4
$animate.enter(element).then(function() {
  $scope.$apply(function() {
    $scope.explode = true;
  });
});

// 1.4+
$animate.enter(element).then(function() {
  $scope.explode = true;
});

Forms(ngMessages, ngOptions)

ngMessages

c9a4421によって、ng-messages-includeの指定場所がng-messagesのattributeからng-messagesの子要素に移動しました。

<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>

ngOptions

7fda214によって、展開されるのvalueの値が、indexやkeyだったものが、hashKeyが出力されるようになります。

<!-- AngularJS 1.3.x -->
<select ng-model="x" ng-option="i in items">
  <option value="1">a</option>
  <option value="2">b</option>
  <option value="3">c</option>
  <option value="4">d</option>
</select>
<!-- AngularJS 1.4.x -->
<select ng-model="x" ng-option="i in items">
  <option value="string:a">a</option>
  <option value="string:b">b</option>
  <option value="string:c">c</option>
  <option value="string:d">d</option>
</select>

ngModelへの反映は変わらないため、valueに依存しない限り影響はありません。
valueに依存している場合はtrack byを使って、回避することができます。

7fda214によって、(key, value) in objsyntaxを使った場合、keyのアルファベット順にソートされていたものが、Object.keys(obj)の順番になります

Templating (ngRepeat, $compile)

ngRepeat

c260e73によって、(key, value) in obj"syntaxを使っている場合、keyのアルファベット順でソートされていたのが、for key in objの順番になります

$compile

6a38dbfによって、directiveのscopeに&で関数を受け取るようにしていて、directive使用時に関数を渡さなかった場合、空の関数がセットされていたが、undefinedがセットされるようになります。

Cookies (ngCookies)

38fbe3eによって、$cookiesのプロパティへのset/getはできなくなり、get/putメソッドを呼び出すようになります。

// < 1.4
var id = $cookies.id;
$cookies.id = id;

// 1.4+
var id = $cookies.get('id');
$cookies.put('id', id);

1.3までは、文字列や数値のcookieへの保存/参照は$cookies、オブジェクトの保存/参照は$cookieStoreというように、分かれていました。1.4からは、$cookiesに以下のメソッドが増え、$cookieStoreはdeprecatedです。

  • get
  • put
  • getObject
  • putObject
  • getAll
  • remove

Server Requests ($http)

5da1256によって、transformRequestによってheaderなどを書き換え可能だったのが、もともと意図した使われ方では無かったため、書き換え不可になります。

// < 1.4
function requestTransform(data, headers) {
    headers = angular.extend(headers(), {
      'X-MY_HEADER': 'abcd'
    });
  }
  return angular.toJson(data);
}

// 1.4+
$http.get(url, {
  headers: {
    'X-MY_HEADER': function(config) {
      return 'abcd'; //you've got access to a request config object to specify header value dynamically
    }
  }
})

Filters(filter, limitTo)

filter

filterされる値にarray以外が指定された場合、何も置きなかったのが、エラーになります

limitTo

limitに不正な値が指定された場合、空のobjectやarrayを返していたのが、そのまま返すように変わります。

おわりに

このように、1.4では大きなBreaking Changeがありません。今、仕事で開発しているものは、$cookiesの修正をするだけで、ほぼテストが通りました。
みなさん早速バージョンアップしていきましょう。使用しているAngularモジュールへのプルリクエストも出すチャンスですので、みんなで修正して1.4の世界で生きていきましょう。
間違いなどあったら、ご指摘・編集リクエストお願いします。

そして、次へ待ち構える1.5や、2.0への準備も忘れずに。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away