AngularJSをサクッと覚える必要があったので勉強したメモ。
生のJSで扱おうと思うとアロー関数使うとうまく動かない箇所があったので、昔ながらの無名関数で書く。
中で呼び出すスクリプト等は学習時に利用した教材に合わせているため古い。
記事中のコードはここにあります
最小限のアプリケーションの作成
AngularJSの仕組みを使って画面に要素を表示するまで。
<html lang="ja" ng-app="sampleApp">
<head>
<meta charset="UTF-8">
<title>sample</title>
<script src="//code.angularjs.org/1.5.0/angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
<body>
<div ng-controller="sampleController">
<h2>{{ msg }}</h2>
</div>
</body>
</html>
const sampleApp = angular.module('sampleApp', []);
sampleApp.controller('sampleController', ['$scope', function ($scope) {
$scope.msg = 'Hello, World!';
}]);
ng-modelによる双方向バインディング
操作によって変更された値を即座に画面に反映する双方向バインディングの仕組みがある。
テキストボックスの操作に応じて表示が変化するのを確かめられるサンプル。
<html lang="ja" ng-app="sampleApp">
<head>
<meta charset="UTF-8">
<title>sample</title>
<script src="//code.angularjs.org/1.5.0/angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
<body>
<div ng-controller="sampleController">
<h2>{{ msg }}</h2>
<input type="text" ng-model="msg">
</div>
</body>
</html>
ngRouteを使ったルーティング
AngularJSではURLの#より後ろの文字列をpathとしてルーティングを行うことができる。
<html lang="ja" ng-app="sampleApp">
<head>
<meta charset="UTF-8">
<title>sample</title>
<script src="//code.angularjs.org/1.5.0/angular.min.js"></script>
<script src="//code.angularjs.org/1.5.0/angular-route.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
<body>
<div ng-view></div>
<a href="#/" class="btn">Sample</a>
<a href="#/sample2" class="btn">Sample2</a>
</body>
</html>
const sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp
.controller('sampleController', ['$scope', function ($scope) {
$scope.msg = 'Hello, World!';
}])
.controller('sampleController2', ['$scope', function ($scope) {
$scope.msg = 'Hello, NewWorld!';
}]);
sampleApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
template: '<h2>{{ msg }}</h2>',
controller: 'sampleController'
})
.when('/sample2', {
template: '<h2>{{ msg }}</h2>',
controller: 'sampleController2'
})
}]);
ルーティング時にpathからパラメータを渡す
ルーティングのpathにパターンを定義して、処理の中で値として利用することができる。
パターンはいくつかあるけど、単純なケースのサンプル。
<html lang="ja" ng-app="sampleApp">
<head>
<meta charset="UTF-8">
<title>sample</title>
<script src="//code.angularjs.org/1.5.0/angular.min.js"></script>
<script src="//code.angularjs.org/1.5.0/angular-route.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
<body>
<div ng-view></div>
<a href="#/" class="btn">Sample</a>
<a href="#/sample2" class="btn">Sample2</a>
</body>
</html>
const sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
template: '<h2>{{ msg }}</h2>',
controller: 'sampleController'
})
.when('/:param', {
template: '<h2>{{ msg }}</h2>',
controller: 'sampleController'
})
}]);
sampleApp
.controller('sampleController',['$scope', '$routeParams', function ($scope, $routeParams) {
$scope.msg = $routeParams.param || 'Hello, World!';
}]);
templateを別のファイルに切り出す
ルーティングのサンプルでは直接記載したtemplateを別ファイルに切り出せるようにする。
const sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'template.html',
controller: 'sampleController'
})
.when('/:param', {
templateUrl: 'template.html',
controller: 'sampleController'
})
}]);
sampleApp
.controller('sampleController',['$scope', '$routeParams', function ($scope, $routeParams) {
$scope.msg = $routeParams.param || 'Hello, World!';
}]);
controllerAsを使って$scopeを使わないでcontrollerを書く
ng-controllerの記述を ng-controller="sampleController as main"
のように変えたり、$routeProviderの指定をcontollerAs
に変えることによって$scopeを利用せず記述することができる。
Angularの考え方に近く、後期に書かれたAngularJSはこちらで書かれていることが多いっぽい。
const sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'template.html',
controller: 'sampleController',
controllerAs: 'ctrl'
})
.when('/:param', {
templateUrl: 'template.html',
controller: 'sampleController as ctrl'
})
}]);
sampleApp
.controller('sampleController',['$routeParams', function ($routeParams) {
this.msg = $routeParams.param || 'Hello, World!';
}]);
AngularJSのService
ビジネスロジックをまとめるための仕組み。
AngularJSの仕組みで名称を指定すると自動でDIされる。($scope、$routeProvider、$routeParamsなど)。
$scope以外は基本的にシングルトンなので、コンポーネント間の値の共有に使われたりする。
Serviceは後述の方法で自作してAngularJSから理由することができる。
Serviceを自作する
const sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'template.html',
controller: 'sampleController',
controllerAs: 'ctrl'
})
.when('/:param', {
templateUrl: 'template.html',
controller: 'sampleController as ctrl'
})
}]);
sampleApp.service('sampleService', function () {
this.firstName = '太郎';
this.lastName = '山田';
this.fullName = () => this.firstName + ' ' + this.lastName;
});
sampleApp
.controller('sampleController', ['$routeParams', 'sampleService', function ($routeParams, sampleService) {
this.msg = ($routeParams.param || 'Hello, World!') + ' ' + sampleService.fullName();
}]);
AngularJSのDirective
Directiveを自作する
AngularJSの世界におけるDirectiveはコンポーネントのようなもので、独自に定義したtemplateや処理をelementやattributeの形で埋め込めるもの。
今回はelementとして扱う単純な例と、親から子のDirectiveにどのように値を渡すかのサンプルを書く
<html lang="ja" ng-app="sampleApp">
<head>
<meta charset="UTF-8">
<title>sample</title>
<script src="//code.angularjs.org/1.5.0/angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
</head>
<body>
<div ng-controller="sampleController as ctrl">
<sample-directive-a value="ctrl.msg"></sample-directive-a>
<sample-directive-b value="ctrl.msg"></sample-directive-b>
<sample-directive-b value="{{ ctrl.msg }}"></sample-directive-b>
<sample-directive-c function="ctrl.upperMsg()"></sample-directive-c>
<input type="text" ng-model="ctrl.msg">
</div>
</body>
</html>
const sampleApp = angular.module('sampleApp', []);
sampleApp
.controller('sampleController', [function () {
this.msg = 'Hello, World!';
this.upperMsg = function () {
return this.msg.toUpperCase();
}
}]);
sampleApp
.directive('sampleDirectiveA', () => {
return {
restrict: 'E',
template: '<h2>{{ value }}</h2>',
scope: {
value: '='
}
}
})
.directive('sampleDirectiveB', () => {
return {
restrict: 'E',
template: '<h2>{{ value }}</h2>',
scope: {
value: '@'
}
}
})
.directive('sampleDirectiveC', () => {
return {
restrict: 'E',
template: '<h2>{{ function() }}</h2>',
scope: {
function: '&'
}
}
});
参考