$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つの役割がある。
- 新しいモジュールを作ること(すなわち、setter)
- 存在するモジュールを参照すること(すなわち、getter)
モジュールを作りたいときは、setter argments(セッター引数?)を使う。
angular.module('myapp', []);
存在するモジュールが欲しいときは、getter arguments(ゲッター引数?)を使う。
angular.module('myapp');
両者の違いは第2引数の有無である
myapp
moduleを一度作ったら、ng-app
directiveを使ってコードの特定の場所にappを埋め込むことができる。
例えばこんな感じに
myApp
は基本的にメインモジュールであり、ページのレンダリングが開始されると同時に自動で呼び出される。
Scopes
$rootscope
はトップレベルのスコープである。これはngApp
directiveがついたDOM要素下のすべての子要素ではどこからでも$rootscope
の変数を参照できることを意味する。(グローバル変数的な扱いになる?)
Dependency Injection
Node.js でいう require 、Java でいう import みたいなもの。
クライアントサイドでは様々なファイルからコードを読み込むからめちゃくちゃ複雑になる場面によく出くわす。ブラウザは違う場所で、違うときにたくさんのファイルを読むこみ、予測できぬ順番で返してくる、ぱねぇ。
AngularJSのDIはそうした問題を解決してくれる。
下のコードを例にすると、$scope
objectと$q
serviceの両方にアクセスできる。
$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
}
};
});
上の例はすべて同じ結果(四輪車)が返ってくる。ならなぜfactory
とprovider
が必要なのだろう?
もし、違う車が欲しいときは、service
を使ってはいけない。factory
とprovider
が必要だ。
例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
}
};
});
画像を見ると、タイヤの数が違うことに気づくだろう。
オブジェクトの中身を変えたいならfactory
とprovider
を、そうでないならservice
を使うとよい。
最後にもう一度
service
は、値の変更ができないぞ。なぜなら、service
は車の概念を提供するものだからfactory
だと、インスタンス化ができるprovider
だと、インスタンス化も、設定も変更できるぞ。
上の画像を見てわかるとおり、app.config(…)
で値を変えている
app.config(function (CarProviderProvider) {
CarProviderProvider.setDealerName('Good');
});
でも、どうしてCarProvider
の代わりにCarProviderProvider
なのだろうか?
それは、app.config(…)
はprovider
のインジェクションを行うためのものであるから。よって、
app.config(function (CarProviderProvider) {
CarProviderProvider.setDealerName('Good');
});
の、CarProviderProvider
は、CarProvider
にProvider
を足した結果である。
なのでprovider
のコードは次のようにすればいい。
app.provider('Car', function....) {
....
});
最終的コードを以下に示す。
まとめ
{foo:1, bar:2}
のような単純なオブジェクトが必要なら、service
を使え。しかし、それのインスタンス化はできない。- オブジェクトのインスタンス化がしたかったら、
factory
を使え。(すなわち、 new Customer(), new Comment()) - 値が変えたいなら、
provider
を使え。(すなわち、 test url, QA url, production url)
とりあえず常にprovider
を使っとけ。
Angular.js: service vs provider vs factory?