AngularJSまとめ

$resource(angular-resource)

長所

  • 外部APIとの連携がしやすくなる。
  • フロント側の処理をAngularJSのみに任せることができ、サーバ側にPHPやNode.jsのAPIのみを実装するという構成を作れる。
  • WebとスマートフォンでAPIを共有できる。

ngResourceはそのままでは使えないので、「angular-resource.js」を読み込む必要がある。

その上で、resourceを使用するmodulenに組み込む

angular.module('app', ['ngResource']);

function GalleryCtrl($scope,$resource) {
  var albums = $resource('https://graph.facebook.com/22092443056/albums');
  $scope.albums = albums.get();
}

非常に単純で、これだけでデータを取得してこれる。

参考

[AngularJS]$resourceを使ってみる。

$sanitize(angular-sanitize / ngSanitize/ service/ $sanitize)

概要

HTMLをエスケープさせずに出力させたいときに使用する。

HTML をエスケープさせずに出力するには、ng-bind-htmlを利用する。

このng-bind-htmlは、別のモジュール(ngSanitize)に分かれているため、angular-sanitize.min.js を index.html で参照し、依存するモジュールとして記述する必要がある。

index.html

app.js

var app = angular.module('app', ['ngSanitize']);

参考

AngularJS で HTML をエスケープさせずに出力するには

$route(angular-route / ngRoute/ service/ $route )

$cookies(angular-cokkies / ngCookies/ service/ $cookies )


Directive

異なった振る舞いを定義するためにHTMLタグを記述する。リストを表現したいときはと。videoであればといった風にだ。しかし、タグの数は有限である。例えば、もし、を使いたかったら?ユーザログインパネルにを使いたかったら?

Directiveは自分だけのタグを生成することができる。

  • ng-click
  • ng-show
  • ng-hide

Modules

Angular.module()には主に2つの役割がある。

  1. 新しいモジュールを作ること(すなわち、setter)
  2. 存在するモジュールを参照すること(すなわち、getter)

モジュールを作りたいときは、setter argments(セッター引数?)を使う。


angular.module('myapp', []);

存在するモジュールが欲しいときは、getter arguments(ゲッター引数?)を使う。


angular.module('myapp');

両者の違いは第2引数の有無である

myappmoduleを一度作ったら、ng-appdirectiveを使ってコードの特定の場所にappを埋め込むことができる。

例えばこんな感じに



  
    
  
  
    
  

myAppは基本的にメインモジュールであり、ページのレンダリングが開始されると同時に自動で呼び出される。

Scopes

$rootscopeはトップレベルのスコープである。これはngAppdirectiveがついたDOM要素下のすべての子要素ではどこからでも$rootscopeの変数を参照できることを意味する。(グローバル変数的な扱いになる?)

Dependency Injection

Node.js でいう require 、Java でいう import みたいなもの。

クライアントサイドでは様々なファイルからコードを読み込むからめちゃくちゃ複雑になる場面によく出くわす。ブラウザは違う場所で、違うときにたくさんのファイルを読むこみ、予測できぬ順番で返してくる、ぱねぇ。

AngularJSのDIはそうした問題を解決してくれる。

下のコードを例にすると、$scopeobjectと$qserviceの両方にアクセスできる。

$scope$qは固定で、もし、$myScopeとかすると動かなくなるぞ。


angular.module('myApp', [])
.controller('HomeController', function($scope, $q) {
  // We have the $scope object and the $q object
  // available in here
});

もしあるカスタムモジュールから別のカスタームモジュールの1つに依存性を注入したいときはmodule関数の第二引数に指定しよう


// say we have some services...
angular.module('fullstack.services', [])
  // some code that defines services here
  .service('WeatherService', function() {
    // define the weather service here
  });
);

// and we want to use those services in our controllers
angular.module('fullstack.controllers', ['fullstack.services'])
  // now we have WeatherService available
);

おまけ(minify対策)


  .controller('HomeController', ['$scope', '$q', function($scope, $q) {
  // ...
}]);

Service

Serviceはシステムのあらゆる領域で振る舞う共通のタスクです(つまり、シングルトンオブジェクト)

シングルトン(singleton)

 

オブジェクトを生成するnewは非常に負荷のかかる処理ですので、使いまわしが効くオブジェクトを毎回newするのはパフォーマンス上問題です。 たとえば、後述のファクトリメソッドパターンで取り上げるファクトリは毎回newする必要がないため、初めに生成したオブジェクトを再利用すぺきです。

 

また、データベースのコネクションプール数を制限したい場合、データベースアクセスオブジェクトの生成数を制限する必要があります。

  

このようにオブジェクトの生成数を制限したいときは、シングルトンパターンの出番です。 このパターンを使えば、オブジェクトを外部から直接生成させることを防ぐことができ、クラス自体に同時に生成できるオブジェクトの数を管理する機能を持たせることができます。

例を挙げると、


angular.module('myApp.services', [])
.service('WeatherService', 
  function($http) {
    this.weatherFor = function(zip) {
    // do something with $http to get the weather here  
  };
});

angular.module('myApp.controllers')
.controller('WeatherController', function($scope, WeatherService) {
  $scope.weather = WeatherService.weatherFor(90210);
});

serviceは一度だけ作られる。あなたのアプリケーションにサービスが与えられたインスタンスがたった1つある。(?)

How to Learn AngularJS - Your AngularJS Sherpa

Service? Factory? Provider?


var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

例2


app.service('CarService', function() {
    this.numCylinder = 4;
});

app.factory('CarFactory', function() {
    return {
        numCylinder: 4
    };
});

app.provider('CarProvider', function() {
    this.$get = function() {
        return {
            numCylinder: 4
        }
    };
});

上の例はすべて同じ結果(四輪車)が返ってくる。ならなぜfactoryproviderが必要なのだろう?

もし、違う車が欲しいときは、serviceを使ってはいけない。factoryproviderが必要だ。

例2-2

6輪車が欲しかったり、8輪車が欲しいときはどうする? serviceだと貰えないんだよなぁ。例を挙げよう。


app.service('CarService', function() {
    this.numCylinder = 4;
});

app.factory('CarFactory', function() {
    return function(numCylinder) {
        this.numCylinder = numCylinder
    };
});

app.provider('CarProvider', function() {
    this.$get = function() {
        return function(numCylinder) {
            this.numCylinder = numCylinder
        }
    };
});

画像を見ると、タイヤの数が違うことに気づくだろう。

オブジェクトの中身を変えたいならfactoryproviderを、そうでないならserviceを使うとよい。

最後にもう一度

  1. serviceは、値の変更ができないぞ。なぜなら、serviceは車の概念を提供するものだから
  2. factoryだと、インスタンス化ができる
  3. providerだと、インスタンス化も、設定も変更できるぞ。

上の画像を見てわかるとおり、app.config(…)で値を変えている


app.config(function (CarProviderProvider) {
    CarProviderProvider.setDealerName('Good');
});

でも、どうしてCarProviderの代わりにCarProviderProviderなのだろうか?

それは、app.config(…)providerのインジェクションを行うためのものであるから。よって、


app.config(function (CarProviderProvider) {
    CarProviderProvider.setDealerName('Good');
});

の、CarProviderProviderは、CarProviderProviderを足した結果である。

なのでproviderのコードは次のようにすればいい。


app.provider('Car', function....) {
    ....
});

最終的コードを以下に示す。

まとめ

  1. {foo:1, bar:2}のような単純なオブジェクトが必要なら、serviceを使え。しかし、それのインスタンス化はできない。
  2. オブジェクトのインスタンス化がしたかったら、factoryを使え。(すなわち、 new Customer(), new Comment())
  3. 値が変えたいなら、providerを使え。(すなわち、 test url, QA url, production url)

とりあえず常にproviderを使っとけ。

Angular.js: service vs provider vs factory?

Recent Posts

Loading...
blog comments powered by Disqus