AngularJSの$resourceを使ったのでメモ

$resourceオブジェクトを使って調べた事メモ

 

公式ドキュメントを順に見て行くと

It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.

空の参照が返って処理が終わるとデータが詰められる?これ分かると便利な機能!!

とりあえずこの件はおいといてwドキュメントを読み進めると

  • HTTP GET "class" actions: Resource.action([parameters], [success], [error])
  • non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
  • non-GET instance actions: instance.$action([parameters], [success], [error])

 

Success callback is called with (value, responseHeaders) arguments. Error callback is called with (httpResponse) argument.

$httpの様にコールバックを登録してレスポンスを受けれるとのこと

取り方はこんな感じ

var Book = $resource('http://xxx.com/webapi/v1/books/:book_id');
Book.get({book_id : 0000},
    function (value, responseHeaders) {
      $scope.book = value;
    },
    function (httpResponse) {
        /* error */
    }

もう一つのコールバックでの取り方はpromiseを使う方法

The Resource instances and collection have these additional properties:

  • $promise: thepromiseof the original server interaction that created this instance or collection.

 っで、空の参照の件に戻って、まずはサンプル

var Book = $resource('http://xxx.com/webapi/v1/books/:book_id');
$scope.book = Book.get({book_id : 0000});

これでおしまいw

ここが$resourceの良いところで、悩んだところ。

get()の戻りで値を確認するとResourceオブジェクトが返ってきてるだけで、値なんて入ってない!

$resourceのコード見ても

          var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
              中略
          if (!isInstanceCall) {
            // we are creating instance / collection
            // - set the initial promise
            // - return the instance / collection
            value.$promise = promise;
            value.$resolved = false;

            return value;
          }

だけど実行すると$scope.bookが更新されてviewに反映される

値見ても確かに反映されてる。。。

っで、もう一度$resourceのコード見ると

shallowClearAndCopy(data, value);

これだっーーーってことで、内部の$httpのpromiseで値詰めてました

ってことで、$resourceはpromiseとfutureオブジェクトを提供してくれるので、$scopeのデータバインディングが利用できるならfutureオブジェクトを利用するのが良いのかなって結論でした

AngularJSのhtml5modeを使いたいけど

AngularJSで書いてみようと思って情報収集すると、大抵$routeProviderでルーティング設定してng-viewでviewを差し替えるサンプルが多く出てくる

 

そんなサンプルを動かしてみるとURLが

http://127.0.0.1:9000/#/test

みたいに"#"がついている

これはフラグメントなので、同一ページでページ遷移してるようにするトリックで、この方法には色々と問題が含まれているらしいけど、その話は置いといて。

 

っで、フラグメントを利用せずに実現するのがHTML5のHistory APIを使った実装らしい。AngularJSでやる場合には

angular.module('testApp', )
  .config(['$locationProvider', function ($locationProvider) {
    $locationProvider.html5Mode(true);
  }
]);

みたいな感じでhtml5modeを有効にしてあげれば

http://127.0.0.1:9000/test

って感じでめでたく"#"が消えましたyo

めでたしめでたし

 

じゃないよね!?

 

 最近はmacで開発が増えているからHTML5に対応したモダンブラウザしか触らないけど、今なお根強い人気??のIE8とかじゃHistory APIには対応していないじゃん!!

なんて心配はちゃんと配慮してあるらしく、HistoryAPIに対応していないブラウザでは

http://127.0.0.1:9000/#/test

に置き換わってHistory APIを利用しないレガシーな動きになるらしい

古くさいWindowsなんてもってないから確認してないけど

これにて一件落着、めでたしめでたし

 

これで終わっちゃダメじゃね!?

 

html5modeを有効にするとルーティング機能が良さげにHistory APIの有効/無効で処理を変えてくれるので、URL体系が"#"無しと有りが共有する事になる。

っで困るのがaタグとかでリンク先を指定するときのパスの書き方

<a href="/test">

って書くとHistory APIが無効の場合に

http://127.0.0.1:9000/test

に飛んでしまう。本当は

http://127.0.0.1:9000/#/test

に飛んで欲しい。

じゃー

<a href="#/test">

って書きたくなるけど、そうするとHitory APIが有効の場合に問題が起きる:(

 

っで、やっと本題。この問題を回避するためには

angular.module('testApp', )
  .controller('PageCtrl', ['$scope', '$location', function ($scope, $location) {
    $scope.linkto = function (path) {
      $location.path(path);
    };
  }
]);

な感じでcontrollerを用意してあげて$locationにpathを設定してあげる。

使い方は

<div ng-controller="PageCtrl">
  <a ng-click="linkto('/test01')">
</div>

って感じで両方のURL体系に対応出来ましたとさ

60>>1の手習い?

30歳を契機に新しい事でもやろうと思ったり、周りの環境が著しく変わったり、人との繋がりがあったりでWeb系のお仕事に変わったけど、それから2年間大した事もせずに時間を過ごしてしまったなぁと思う今日この頃で。

 

エンジニアから離れていたのもあったので、もう一度エンジニアしてみようかなぁとやんわり思い、今更Web系のお勉強を始めるよってことで

 

Web系ならインフラ周りを学びたいけど、とっかかりがないので、上物のアプリケーションから手を出して、徐々に下回りにいけたらなぁ

 

とにかくエンジニアを名乗るならモノを作らにゃ始まらんので、Rails、AngularJS、Bootstrapあたりのミーハーチョイスで始めよう

エンジニア向けトークイベントに行ってきた

懇親会に出て、土曜であることを忘れてタクシー帰りで日が変わってしまったけど、21日にお茶の水でエンジニア向けトークイベントに行ってきた

 

「やりがい」「働きがい」「稼ぎがい」あるエンジニアライフを語る、忘年会トーク

 

ゲストスピーカーのSKIYAKI 飯田さん、Lang-8 佐々木さん、フリークアウト 久森さんとの距離感も程よく、色々とお話をさせていただいて大変有意義な時間を過ごせた。

色々な話をしたけれども、結局は自分でやりたいと思ったことをやってみる。当たり前なことだけど、自分でやって消化してかないとだよねと改めて実感したり。

そんな訳で、今日はおすすめされたブログを書いてみるから初めてみる。ちゃんと自分なりに効果を検証してみましょうってことで。

 

今回のイベント参加で飯田さんからヘリコプターのラジコンを頂いてしまいました。ありがとうございました。明日朝から遊ばせてもらうので、エネループをチャージして今日は就寝。