5
4

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.

angular-resourceでローカルjsonファイルを読み込み、ngStorageでWebStorageにデータを保存して扱う方法

Last updated at Posted at 2015-12-20

概要

タイトルのとおりです。そんな需要があるのかないのかわかりませんが、勉強になったのでメモ代わりに。

前提、動機

以下のようなデータを初期値としてファイルから読み込みたかったのですが、データの保存も考慮するとファイル書き込みよりもWebStorage(僕の場合はLocalStorage)に保存して扱いたいと思ったのがきっかけです。
HTML5アプリ(Android/iOS)だったので、ファイル保存手段としてngResourceのPOSTメソッドを使えなかったという事もあります。

data.json
[
  {
    "author": "Archer",
    "title": "Aces: nothing else comes close."
  },{
    "author": "Chopper",
    "title": "Rock'n Roll is my life."
  },{
    "author": "Edge",
    "title": "let me fly as your wingman just a little while longer..."
  },{
    "author": "Swordsman",
    "title": "Faces of Aces"
  }
]

用語

  • angular-resource = ngResource = $resource: 同じことです。最初は区別しようと思っていたのですが断念。。
  • ngStorage = $storage: 同じです。

解決策の概要

  • 初期値ファイルの読み込みにはngResource(angular-resource)を使います。
    ただし、書き込み(POST)はサーバ側の実装が必要になるので読み込み(GET)のみ使います。
  • WebStorageはngStorageを用いました。$watchを使った双方向バインディングが強力です。

手段の詳細

1. angular-resourceとngStorageをインストールする。

bower install ngstorage angular-resource

  • ng'S'torageではなく、sを小文字で入力してください。
  • --saveオプションをつけた方がbower.jsonに依存性を保存できるので便利ですね。

2. index.htmlでライブラリのjsファイルと自分のjsファイルをincludeします。

index.html
<!doctype html>
<html>
  <head><meta charset="utf-8">
    <!-- angular, angular-resource, ngStorageを読み込み -->
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/angular-resource/angular-resource.js"></script>
    <script src="bower_components/ngstorage/ngStorage.js"></script>
    <!-- メインロジックを読み込み -->
    <script src="app.js"></script>
  </head>

  <body ng-app="StrageTestApp">
    <div ng-controller="MainCtrl as mc"> <!-- 以降mcでアクセス可能 -->
      <ul>
        <li ng-repeat="i in mc.items">
          author: <input ng-model="i.author">
          title: <input ng-model="i.title">
        </li>
      </ul>
    </div>

  </body>
</html>

3. Javascriptでangularのコードを記載します。以下、ポイントです。

  • angular.moduleでngResourceとngStorageをinjectします。
  • Local Storageを使う場合はconfigで$localStorageProviderに
    prefixをつけた方がbetterです。
    同サイトの他のwebアプリとデータが混在してしまうためです。
    Session Storageの場合はあまり気にならないと思います。
  • factoryでデータの読み込みとLocal Storageへのバインドを行います。
    • ngResourceは遅延実行される点がポイントです。$promiseを使いましょう。
app.js
'use strict';

/**
 * app definition
 * ここでngResourceとngStorageをinjectionする
 */
angular.module('StrageTestApp', [
  'ngResource',
  'ngStorage'
])
.config(['$localStorageProvider',
    function ($localStorageProvider) {
        // prefixをつけないと他のwebアプリと混在してしまいます。
        $localStorageProvider.setKeyPrefix('StrageTest');
    }]);

/**
 * controller
 * サービスとindex.htmlとの橋渡しをする。
 */
angular.module('StrageTestApp')
  .controller('MainCtrl', ['MainService', function(MainService){
    // $scopeでもOKです。
    this.items = MainService.all(); // $localStorageをitemsへ
  }]);

/**
 * service(factoryサービス)
 * 1. ngResourceでdata.jsonから読み込む
 * 2. 1.をlocalStorageに保存する
 *    - session storageを使いたい場合は$sessionStorageを。
 * all: localStorageオブジェクトを返却するメソッド
 */
angular.module('StrageTestApp')
  .factory('MainService', ['$resource', '$localStorage',
    function($resource, $localStorage){

      // $resource(ngResource)を使って読み込む
      var res = $resource('data.json');

      // $resourceは遅延実行なので$promiseを使ってデータを取得できるまで
      // 待ってから$localStorageへ保存
      var data = res.query();
      data.$promise.then(function(){
        $localStorage.$default(data); // localStorageの$defaultへ
      });

      // factoryサービスのreturn部
      return{
        all: function(){
          return $localStorage; // $localStorageを返す
        }
      };
    }]);

動作結果

  • 一度バインドしてしまえば、angularの双方向バインドが効き、一文字単位で入力内容が
    Web Storageに反映されます。非常に便利だと思います。

1.png

2.png

議論、future work

  • 全てをローカルで実施したい場合は使いやすいのではないかと思います。
  • ngStorageのprefixはまだ課題があるようでしたが (参考1)、今は特に問題なさそうに見えます
    。どなたか情報あれば。

参考リンク

AngularJSでの非同期処理
本家:$resourceのドキュメント
GitHub:ngStorage
参考1: webStorage を便利に使う angularJS用モジュールを作った by amoO_O氏

5
4
4

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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?