目次
バインドされたデータを加工する仕組み。
単一の値用と配列用とがある。
(function () {
var app = angular.module("MemberManager");
// 性別フィルタ
// 'male'なら'男'、'female'なら'女'を返す
app.filter("gender", function () {
return function (value) {
if (value == 'male') return '男';
if (value == 'female') return '女';
return '?';
};
});
// 性別選別フィルタ
// 指定した性別だけを通す
// m : 男性
// f : 女性
// b : 両方
// それ以外 : 何も通さない
app.filter('genderSelect', function () {
return function (values, flag) {
if (!angular.isArray(values)) return values;
if (flag == 'b') return values;
var newValues = [];
angular.forEach(values, function (v) {
if ((flag == 'm' && v.gender == 'male') ||
(flag == 'f' && v.gender == 'female'))
newValues.push(v);
});
return newValues;
}
});
}());
ListControllerのスコープにflagを追加した。この値を見て、list.htmlで表示する性別を切り替える。
(function () {
var app = angular.module("MemberManager");
// アプリケーションコントローラ
app.controller("AppController", function ($scope, $location) {
$scope.changeUrl = function (url) {
$location.path(url);
}
});
// リストコントローラ
app.controller("ListController", function ($scope, MemberService) {
$scope.members = MemberService.members;
$scope.flag = 'm';
});
// 新規登録コントローラ
app.controller("RegistController", function ($scope, MemberService) {
$scope.name = "jiro";
$scope.gender = "";
$scope.mail = "jiro@aaa.jp";
$scope.bloodtype = "AB";
// 新規作成が押された
$scope.registClicked = function () {
MemberService.regist($scope.name, $scope.gender,
$scope.mail, $scope.bloodtype);
$scope.changeUrl('/');
};
});
// 修正コントローラ
app.controller("ModifyController", function ($scope, $routeParams, MemberService) {
var m = MemberService.members[$routeParams.num];
$scope.num = $routeParams.num;
$scope.mem = new MemberService.Member();
$scope.mem.id = m.id;
$scope.mem.name = m.name;
$scope.mem.gender = m.gender;
$scope.mem.mail = m.mail;
$scope.mem.bloodtype = m.bloodtype;
// 修正ボタンが押された
$scope.modify = function () {
MemberService.modify($scope.num, $scope.mem);
$scope.changeUrl('/');
};
// 削除ボタンが押された
$scope.delete = function () {
MemberService.delete($scope.num);
$scope.changeUrl('/');
};
});
}());
(function () {
var app = angular.module("MemberManager");
// 会員クラス
// id : シリアル番号
// name : 氏名
// gender : 性別
// mail : メールアドレス
// bloodtype : 血液型
// modified : 修正日時
var Member = function (id, nm, ge, ma, bt, mo) {
this.id = id;
this.name = nm;
this.gender = ge;
this.mail = ma;
this.bloodtype = bt;
this.modified = mo;
};
// 会員サービス
app.factory("MemberService", function () {
var ms = {} // サービスの実体
ms.s_max = 0; // 会員番号の最大値
ms.members = []; // 会員リスト
ms.Member = Member; // 会員コンストラクタ
// 新規会員の登録
ms.regist = function (nm, ge, ma, bt) {
ms.members.push(new ms.Member(++ms.s_max,
nm, ge, ma, bt, new Date()));
};
// 会員情報の修正
ms.modify=function(num,mem){
var m=ms.members[num];
m.name=mem.name;
m.gender=mem.gender;
m.mail=mem.mail;
m.bloodtype=mem.bloodtype;
m.modified=new Date();
}
// 会員情報の削除
ms.delete=function(num){
ms.members.splice(num,1);
};
return ms;
});
}());
(function () {
var app = angular.module("MemberManager", ['ngRoute']);
// ルーティング
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'list.html',
controller: 'ListController'
})
.when('/regist', {
templateUrl: 'regist.html',
controller: 'RegistController'
})
.when('/modify/:num', {
templateUrl: 'modify.html',
controller: 'ModifyController'
})
.otherwise({
redirectTo: '/'
});
});
// 初期化
app.run(function (MemberService) {
MemberService.regist("john", "male", "john@aaaa.jp", "A");
MemberService.regist("paul", "male", "paul@bbbb.uk", "B");
MemberService.regist("marry", "female", "marry@cccc.jp", "O");
});
}());
表示する性別を選択できるようにした。ng-modelでListControllerのflagと結んでいる。
<p>
<button ng-click="changeUrl('regist')">新規登録</button>
</p>
<select ng-model="flag">
<option value='b'>両方</option>
<option value='m'>男</option>
<option value='f'>女</option>
<option value=''>なし</option>
</select>
<table border="1" width="100%">
<tr>
<th>ID</th>
<th>氏名</th>
<th>性別</th>
<th>メール</th>
<th>血液型</th>
<th>更新日</th>
</tr>
<tr ng-repeat="m in members|genderSelect:flag">
<td>{{m.id}}</td>
<td><a href="#/modify/{{$index}}">{{m.name}}</a></td>
<td>{{m.gender|gender}}</td>
<td>{{m.mail}}</td>
<td>{{m.bloodtype}}</td>
<td>{{m.modified | date:'yyyy年MM月dd日 HH時mm分ss秒'}}</td>
</tr>
</table>
フォームの入力欄に入力されるデータを検証できる機能。
<h3>新規登録</h3>
<p>新しい会員情報を入力してください。</p>
<form novalidate name="RF">
<p>氏名:
<input type="text" name="NM" ng-model="name" required/>
<span ng-show="RF.NM.$invalid">※必須項目です</span>
</p>
<p>性別:
<input type="radio" name="gender" value="male" ng-model="gender" />男
<input type="radio" name="gender" value="female" ng-model="gender" />女</p>
<p>メール:
<input type="email" name="MA" ng-model="mail" required/>
<span ng-show="RF.MA.$invalid">※必須項目です</span>
</p>
<p>血液型:
<select ng-model="bloodtype">
<option>A</option>
<option>B</option>
<option>AB</option>
<option>O</option>
</select>
</p>
<p>
<button ng-click="registClicked()" ng-disabled="RF.$invalid">
新規登録
</button>
<button onclick="history.back()">キャンセル</button>
</p>
</form>
<!doctype html>
<html ng-app="MemberManager">
<head>
<meta charset="utf-8">
<title>会員管理システム</title>
<script type="text/javascript" src="vendors/jquery-2.1.4.js"></script>
<script type="text/javascript" src="vendors/angular.js"></script>
<script type="text/javascript" src="vendors/angular-route.js"></script>
<script type="text/javascript" src="vendors/bootstrap-3.3.6-dist/js/bootstrap.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<script type="text/javascript" src="js/services.js"></script>
<script type="text/javascript" src="js/filters.js"></script>
<link rel="stylesheet" href="vendors/bootstrap-3.3.6-dist/css/bootstrap.css">
</head>
<body ng-controller="AppController">
<div class="panel panel-default">
<div class="panel-heading">
<h1>会員管理システム <small>Ver 0.1</small></h1>
</div>
<div class="panel-body">
<div ng-view></div>
</div>
</body>
</html>
<p>
<button class="btn btn-default" ng-click="changeUrl('regist')">
新規登録
</button>
</p>
<select class="form-control" ng-model="flag">
<option value='b'>両方</option>
<option value='m'>男</option>
<option value='f'>女</option>
<option value=''>なし</option>
</select>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>氏名</th>
<th>性別</th>
<th>メール</th>
<th>血液型</th>
<th>更新日</th>
</tr>
</thead>
<tr ng-repeat="m in members|genderSelect:flag">
<td>{{m.id}}</td>
<td><a href="#/modify/{{$index}}">{{m.name}}</a></td>
<td>{{m.gender|gender}}</td>
<td>{{m.mail}}</td>
<td>{{m.bloodtype}}</td>
<td>{{m.modified | date:'yyyy年MM月dd日 HH時mm分ss秒'}}</td>
</tr>
</table>
<div class="panel panel-default">
<div class="panel-heading">
<h4>新規登録</h4>
</div>
<div class="panel-body">
<p>新しい会員情報を入力してください。</p>
<form novalidate name="RF">
<div class="form-group">氏名:
<input type="text" class="form-control" name="NM" ng-model="name" required/>
<span ng-show="RF.NM.$invalid">※必須項目です</span>
</div>
<div class="form-group">性別:
<div class="radio-inline">
<input type="radio" name="gender" value="male" ng-model="gender" />男
</div>
<div class="radio-inline">
<input type="radio" name="gender" value="female" ng-model="gender" />女
</div>
</div>
<div class="form-group">メール:
<input type="email" class="form-control" name="MA" ng-model="mail" required/>
<span ng-show="RF.MA.$invalid">※必須項目です</span>
</div>
<div class="form-group">血液型:
<select class="form-control" ng-model="bloodtype">
<option>A</option>
<option>B</option>
<option>AB</option>
<option>O</option>
</select>
</div>
<p>
<button class="btn btn-success" ng-click="registClicked()" ng-disabled="RF.$invalid">
新規登録
</button>
<button class="btn btn-default" onclick="history.back()">キャンセル</button>
</p>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3>会員情報の修正</h3>
</div>
<div class="panel-body">
<p>会員情報を修正してください。</p>
<form name="MF">
<p>ID:{{mem.id}}</p>
<div class="form-group">氏名:
<input type="text" class="form-control" name="NM" ng-model="mem.name" required/>
<span ng-show="MF.NM.$invalid">※必須項目です</span>
</div>
<div class="form-group">性別:
<div class="radio-inline">
<input type="radio" name="gender" value="male" ng-model="mem.gender" />男
</div>
<div class="radio-inline">
<input type="radio" name="gender" value="female" ng-model="mem.gender" />女
</div>
</div>
<div class="form-group">メール:
<input type="email" class="form-control" name="MA" ng-model="mem.mail" required/>
<span ng-show="MF.MA.$invalid">※必須項目です</span>
</div>
<div class="form-group">血液型:
<select class="form-control" ng-model="mem.bloodtype">
<option>A</option>
<option>B</option>
<option>AB</option>
<option>O</option>
</select>
</div>
<p>
<button class="btn btn-success" ng-disabled="MF.$invalid" ng-click="modify()">修正</button>
<button class="btn btn-default" onclick="history.back()">キャンセル</button>
<button class="btn btn-danger" ng-click="delete()">削除</button>
</p>
</form>
</div>
</div>
本研修で使用するサーバーはさくらサーバーである。
URLは、http://seminar-senior.jeez.jp となっている。
これは、中堅SE向け研修用に取得したドメインである。
FTPサーバーも同じ名前である。 ユーザ名、パスワードはセミナー中に示す。
DBとしてMySQLが利用できる。
サーバー名はmysql514.db.sakura.ne.jpであるが、これは上記のウェブサーバーのみからアクセス可能である。
データベース管理ツールはphpMyAdminがここから使用できる。
ユーザ名、パスワードはセミナー中に示す。
(function () {
var app = angular.module("MemberManager");
// 会員クラス
// id : シリアル番号
// name : 氏名
// gender : 性別
// mail : メールアドレス
// bloodtype : 血液型
// modified : 修正日時
var Member = function (id, nm, ge, ma, bt, mo) {
this.id = id;
this.name = nm;
this.gender = ge;
this.mail = ma;
this.bloodtype = bt;
this.modified = mo;
};
// 会員サービス
app.factory("MemberService", function ($http) {
var ms = {} // サービスの実体
ms.s_max = 0; // 会員番号の最大値
ms.members = []; // 会員リスト
ms.Member = Member; // 会員コンストラクタ
// 新規会員の登録
ms.regist = function (nm, ge, ma, bt) {
ms.members.push(new ms.Member(++ms.s_max,
nm, ge, ma, bt, new Date()));
};
// 会員情報の修正
ms.modify = function (num, mem) {
var m = ms.members[num];
m.name = mem.name;
m.gender = mem.gender;
m.mail = mem.mail;
m.bloodtype = mem.bloodtype;
m.modified = new Date();
}
// 会員情報の削除
ms.delete = function (num) {
ms.members.splice(num, 1);
};
// サーバーからデータをロードする
ms.load = function () {
$http({
method: 'post',
url: 'http://seminar-senior.jeez.jp/fuchida/MemberManager/php/getMember.php'
})
.success(function (data, status, headers, config) {
console.log(data);
for (var i in data) {
ms.members.push(new ms.Member(data[i].id,
data[i].name,
data[i].gender,
data[i].mail,
data[i].bloodtype,
new Date(data[i].modified)));
}
})
.error(function (data, status, headers, config) {
alert("MemberServce: load error");
});
};
return ms;
});
}());
(function () {
var app = angular.module("MemberManager", ['ngRoute']);
// ルーティング
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'list.html',
controller: 'ListController'
})
.when('/regist', {
templateUrl: 'regist.html',
controller: 'RegistController'
})
.when('/modify/:num', {
templateUrl: 'modify.html',
controller: 'ModifyController'
})
.otherwise({
redirectTo: '/'
});
});
// 初期化
app.run(function (MemberService) {
MemberService.load();
//MemberService.regist("john", "male", "john@aaaa.jp", "A");
//MemberService.regist("paul", "male", "paul@bbbb.uk", "B");
//MemberService.regist("marry", "female", "marry@cccc.jp", "O");
});
}());
<?php
try{
$pdo=new PDO("mysql:host=mysql514.db.sakura.ne.jp;".
"dbname=forcreate_fuchida;".
"charset=utf8",
"forcreate","junior2015");
$q="select * from member";
$s=$pdo->prepare($q);
$s->execute();
print json_encode($s->fetchAll());
}catch(PDOException $e){
print json_encode(array("msg"=>$e->getMessage()));
}
?>