โดยในหน้าจะประกอบด้วยส่วนของเมนูและส่วนของรายการที่สั่ง
ไฟล์ index.html ตั้งต้น
<div class="container">
<div class="row" ui-view>
</div>
</div>
- สร้าง state ชื่อ sushi
- ทำการดึงข้อมูล sushi จาก resolve โดยมีรายละเอียดดังนี้
- {{item.name}} ราคา {{item.price}} yen
- กำหนด templateUrl เป็น shop.html
shop.html
<div class="col-md-8">
<ul class="nav nav-pills navbar-default">
<li><a ui-sref="sushi">Sushi</a></li>
</ul>
<div>
<div class="list-group">
<div class="list-group-item row" ng-repeat="item in menuItem" ng-init="item.quantity = 0">
<h2 class="col-md-4">\{\{item.name}}</h2>
<div class="col-md-2"><em>\{\{item.price | number:2}} Yen </div>
<div class="col-md-2"><p>X \{\{item.quantity}}</p> <button class="btn btn-default" ng-click="increase(item)">increse</button>
<button class="btn btn-default" ng-click="decrease(item)">decrese</button></div>
<div class="col-md-2"><button class="btn btn-default pull-right" ng-click="orderCall(item)">+</button></div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="list-group">
<div class="list-group-item row" ng-repeat="item in orderItem">
<h2 class="col-md-4">\{\{item.name}}</h2>
<div class="col-md-4"><em>\{\{item.price | number:2}} Yen </div>
<div class="col-md-2"><p>X \{\{item.quantity}}</p></div>
<div class="col-md-2"><button class="btn btn-default pull-right" ng-click="removeOrder(item)">X</button></div>
</div>
<button ng-show="orderItem.length > 0" ng-click="checkOut()" class="btn btn-danger col-md-12">Check Out</button>
</div>
</div>
</div>
- กำหนด controller ให้มีรายละเอียดดังนี้
controller: function ($scope, sushiItem) {
$scope.orderItem = [];
$scope.menuItem = sushiItem;
$scope.increase = function (item) { };
$scope.decrease = function (item) { };
$scope.orderCall = function (item) { };
$scope.removeOrder = function (item) { };
$scope.checkOut = function () { };
}
Answer of Checkpoint 1
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('sushi', {
url: '/sushi',
resolve: {
sushiItem: function () {
var item = [
{name: "Otaro", price: 200},
{name: "Maguro", price: 300},
{name: "Tamago", price: 120},
{name: "Saba", price: 100},
{name: "Tako", price: 150}
];
return item;
}
},
templateUrl: 'shop.html',
controller: function ($scope, sushiItem) {
$scope.orderItem = [];
$scope.menuItem = sushiItem;
$scope.increase = function (item) { };
$scope.decrease = function (item) { };
$scope.orderCall = function (item) { };
$scope.removeOrder = function (item) { };
$scope.checkOut = function () { };
}
});
จากรูปสังเกตได้ว่าในหน้านี้มีส่วนที่เหมือนกัน คือ [ส่วนของประเภทอาหาร]และ[ส่วนรายการที่สั่ง]
และส่วนที่ต่างกันคือ ข้อมูลใน [ส่วนของเมนูอาหาร]
เราจึงทำการสร้าง abstract state ชื่อว่า shop เป็น template ให้สามารถ reuse ส่วนต่างๆของ template ได้
โดยจะแบ่ง view ของเป็น 3 หน้าดังนี้
- shop.html
<div class="col-md-8">
<ul class="nav nav-pills navbar-default">
<li><a ui-sref="sushi">Sushi</a></li>
<li><a ui-sref="appetizer">Appetizer</a></li>
<li><a ui-sref="drink">Drink</a></li>
</ul><div ui-view="menulist"></div></div>
<div class="col-md-4" ui-view="order">
</div>
</div>
- menu.html
<div class="list-group">
<div class="list-group-item row" ng-repeat="item in menuItem" ng-init="item.quantity = 0">
<h2 class="col-md-4">\{\{item.name}}</h2>
<div class="col-md-2"><em>\{\{item.price | number:2}} Yen </div>
<div class="col-md-2"><p>X \{\{item.quantity}}</p> <button class="btn btn-default" ng-click="increase(item)">increse</button>
<button class="btn btn-default" ng-click="decrease(item)">decrese</button></div>
<div class="col-md-2"><button class="btn btn-default pull-right" ng-click="orderCall(item)">+</button></div>
</div>
</div>
- order.html
<div class="list-group">
<div class="list-group-item row" ng-repeat="item in orderItem">
<h2 class="col-md-4">\{\{item.name}}</h2>
<div class="col-md-4"><em>\{\{item.price | number:2}} Yen </div>
<div class="col-md-2"><p>X \{\{item.quantity}}</p></div>
<div class="col-md-2"><button class="btn btn-default pull-right" ng-click="removeOrder(item)">X</button></div>
</div>
<button ng-show="orderItem.length > 0" ng-click="checkOut()" class="btn btn-danger col-md-12">Check Out</button>
</div>
จากนั้นทำการสร้าง shop state ขึ้นมา โดย
เมื่อเราต้องการใช้ส่วนต่างๆของ shop state ก็ทำการกำหนดให้เป็น child state
กำหนด sushi state เป็น child state ของ shop
- กำหนดให้ sushi เป็น child state ของ shop
- กำหนด views แทนการใช้ templateUrl โดยมี 2 views ดังนี้
- menulist
- กำหนด templateUrl ไปที่ menu.html
- กำหนด resolve ให้ดึงข้อมูล sushi มาแสดง
- ใน controller ทำการกำหนดค่าให้กับ menuItem
- order
- กำหนดให้ templateUrl ไปที่ order.html
เพิ่ม appetizer state และ drink state โดยจะมีลักษณะ interface เหมือนกับ sushi
- appetizer state จะมีข้อมูลที่ต้อง resolve ดังนี้
- {{item.name}} ราคา {{item.price}} yen
- drink state จะมีข้อมูลที่ต้อง resolve ดังนี้
- {{item.name}} ราคา {{item.price}} yen
Answer of Checkpoint 2
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('shop', {
abstract: true
templateUrl: 'shop.html',
controller: function ($scope, sushiItem) {
$scope.orderItem = [];
$scope.menuItem = sushiItem;
$scope.increase = function (item) { };
$scope.decrease = function (item) { };
$scope.orderCall = function (item) { };
$scope.removeOrder = function (item) { };
$scope.checkOut = function () { };
}
})
.state('shop.sushi', {
url: '/sushi',
resolve: {
sushiItem: function () {
var item = [
{name: "Otaro", price: 200},
{name: "Maguro", price: 300},
{name: "Tamago", price: 120},
{name: "Saba", price: 100},
{name: "Tako", price: 150}
];
return item;
}
},
views: {
"menulist": {
templateUrl: 'menu.html',
controller: function ($scope, sushiItem) {
$scope.menuItem = sushiItem;
}
},
"order": {
templateUrl: 'order.html'
}
}
})
.state('shop.appetizer', {
url: '/appetizer',
resolve: {
sushiItem: function () {
var item = [
{name: "Takoyaki", price: 500},
{name: "Okonomiyaki", price: 500},
{name: "Yakisoba", price: 650},
{name: "Soba", price: 400}
];
return item;
}
},
views: {
"menulist": {
templateUrl: 'menu.html',
controller: function ($scope, sushiItem) {
$scope.menuItem = sushiItem;
}
},
"order": {
templateUrl: 'order.html'
}
}
})
.state('shop.drink', {
url: '/drink',
resolve: {
sushiItem: function () {
var item = [
{name: "Coke", price: 100},
{name: "Water", price: 100},
{name: "Lemon Soda", price: 250},
{name: "Matcha", price: 200}
];
return item;
}
},
views: {
"menulist": {
templateUrl: 'menu.html',
controller: function ($scope, sushiItem) {
$scope.menuItem = sushiItem;
}
},
"order": {
templateUrl: 'order.html'
}
}
});
- increase(item) - เพิ่มจำนวนซูชิที่ต้องการ
- decrease(item) - ลดจำนวนซูชิที่ต้องการ [hint: จำนวนไม่น้อยกว่า 0]
- orderCall(item) - เพิ่มรายการที่สั่งลง orderItem [hint: push()]
- removeOrder(item) - ลบรายการที่สั่งออกจาก orderItem [hint: splice()]
Answer of Checkpoint 3
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('shop', {
abstract: true
templateUrl: 'shop.html',
controller: function ($scope, sushiItem) {
$scope.orderItem = [];
$scope.menuItem = sushiItem;
$scope.increase = function (item) {
if (item.quantity !== null) {
item.quantity += 1;
}
};
$scope.decrease = function (item) {
if (item.quantity !== null && item.quantity > 0) {
item.quantity -= 1;
}
};
$scope.orderCall = function (item) {
if (item.quantity !== null && item.quantity > 0) {
var addItem = angular.copy(item);
$scope.orderItem.push(addItem);
item.quantity = 0;
}
};
$scope.removeOrder = function (item) {
var index = $scope.orderItem.indexOf(item);
$scope.orderItem.splice(index, 1);
}
$scope.checkOut = function () { };
}
})
.state('shop.sushi', { ... })
.state('shop.appetizer', { ... })
.state('shop.drink', { ... });
สร้าง checkout state ขึ้นมา
- กำหนด templateUrl เป็น checkout.html
checkout.html
<div>
<ul class="nav nav-pills navbar-default">
<li><a ui-sref="sushi">Back</a></li>
</ul>
</div>
<div class="list-group">
<div class="list-group-item row" ng-repeat="item in orderItem">
<h2 class="col-md-4">\{\{item.name}}</h2>
<div class="col-md-4">
<em>\{\{item.price | number:2}} Yen X \{\{item.quantity}} = \{\{item.quantity * item.price}} Yen
</div>
</div>
<div class="list-group-item row" >
<h2 class="col-md-4">Total</h2>
<h2 class="col-md-4">\{\{sum}} Yen</h2>
</div>
<button ng-click="payMoney()" class="btn btn-danger col-md-12">Pay</button>
</div>
- กำหนด params ให้รับค่า orderItem
params: {'orderItem':''}
- กำหนดรายละเอียดของ controller ดังนี้
function ($scope, $stateParams, $state) {
$scope.orderItem = $stateParams.orderItem;
$scope.sum = 0;
angular.forEach($scope.orderItem, function (item) {
$scope.sum += (item.price * item.quantity);
});
$scope.payMoney = function () {
alert("Thank you.");
$state.go('menu.sushi');
}
}
แต่เรายังหาทางไปยัง checkout ไม่ได้ ฉะนั้นให้ทำการกำหนดฟังก์ชั่น checkOut() ใน shop state
- กำหนดให้ map "orderItem" เข้ากับค่าของ orderItem ใส่ลงในตัวแปร params
- ส่งค่า params ไปยัง checkout state
Answer of Checkpoint 4
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('shop', {
abstract: true
templateUrl: 'shop.html',
controller: function ($scope, sushiItem) {
$scope.orderItem = [];
$scope.menuItem = sushiItem;
...
$scope.checkOut = function () {
var params = {"orderItem":$scope.orderItem};
$state.go("checkout", params);
};
}
})
.state('shop.sushi', { ... })
.state('shop.appetizer', { ... })
.state('shop.drink', { ... })
.state('checkout', {
url: '/checkout',
params: {'orderItem':''},
templateUrl: 'checkout.html',
controller: function ($scope, $stateParams, $state) {
$scope.orderItem = $stateParams.orderItem;
$scope.sum = 0;
angular.forEach($scope.orderItem, function (item) {
$scope.sum += (item.price * item.quantity);
});
$scope.payMoney = function () {
alert("Thank you.");
$state.go('shop.sushi');
}
}
});
สามารถดูผลลัพธ์ที่เสร็จแล้วได้ ที่นี่