สิ่งที่ควรรู้
onEnter & onExit property
onEnter เป็น property ของ state จะถูกเรียกใช้เมื่อก่อนที่จะเริ่มต้น state นั้นๆ สามารถนำไปใช้กับการตรวจสอบ permission ได้
onExit เป็น property ของ state จะถูกเรียกใช้เมื่อก่อนที่จะออกจาก state นั้นๆ โดยส่วนมากมักจะใช้ในการยืนยันข้อมูลพวก modal dialog ต่างๆ
$stateProvider.state("stateName", {
template: 'someHtml',
resolve: { 'someData': 'someValue' },
controller: function($scope, someData){
...
},
onEnter: function(someData){
if(someData){ /*** do something ***/ }
},
onExit: function(someData){
if(someData){ /*** do something ***/ }
}
})
การทำงานของ ฟังก์ชั่นใน state จะเรียงลำดับตามนี้
State Change Events
Event ที่เกี่ยวข้องกับการเปลี่ยนแปลง state มีทั้งหมด 4 Event
- $stateChangeStart
- $stateNotFound
- $stateChangeSuccess
- $stateChangeError
โดย Event ทั้งหมดนั้นจะอยู่ภายใต้ scope ของ $rootScope
$stateChangeStart
Event นี้จะถูกใช้ เมื่อเริ่มการเปลี่ยนจาก state ปัจจุบันไปยัง state ถัดไป
โดยจะมีโครงสร้างฟังก์ชั่นดังนี้
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
...
});
$stateNotFound
Event นี้จะถูกใช้ เมื่อเรียกใช้งาน state ที่ไม่มีอยู่
โดยจะมีโครงสร้างฟังก์ชั่นดังนี้
$rootScope.$on('$stateNotFound',
function(event, unfoundState, fromState, fromParams){
console.log(unfoundState.to); // unfound State
console.log(unfoundState.toParams); // state parameter
console.log(unfoundState.options); // options
});
$stateChangeSuccess
Event นี้จะถูกใช้ เมื่อการเปลี่ยนจาก state ปัจจุบันไปยัง state ถัดไปเสร็จสิ้น
โดยจะมีโครงสร้างฟังก์ชั่นดังนี้
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
...
});
$stateChangeError
Event นี้จะถูกใช้ เมื่อเกิดข้อผิดพลาดขึ้นระหว่างการเปลี่ยน state โดยส่วนมากจะเป็นข้อผิดพลาดที่ไม่สามารถโหลด resolve promise ได้
โดยจะมีโครงสร้างฟังก์ชั่นดังนี้
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error){
...
});
การเปลี่ยน state จะมี event เรียงลำดับตามนี้
View Load Events
Event ที่เกี่ยวข้องกับการโหลดหน้าเว็บ (view) มีทั้งหมด 2 Event
- $viewContentLoading
- $viewContentLoaded
โดย Event ทั้งหมดนั้นจะอยู่ภายใต้ scope ของ $rootScope
$viewContentLoading
Event นี้จะถูกใช้ เมื่อเริ่มมีการโหลดหน้าเว็บ ก่อนที่จะทำการ render DOM โดยใช้ $broadcast ในการส่ง event
$scope.$on('$viewContentLoading',
function(event, viewConfig){
// Access to all the view config properties.
// and one special property 'targetView'
// viewConfig.targetView
});
$viewContentLoaded
Event นี้จะถูกใช้ หลังจากการ render DOM เสร็จสิ้น โดยใช้ $emit ในการส่ง event
$scope.$on('$viewContentLoaded', function(event){
...
});
ตัวอย่างการทำงานของ Event ต่างๆ
ใน config กำหนด state ขึ้นมา 3 state
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('one', {
url: '/one',
template: '<p>this is state one</p><p ui-view></p>'
})
.state('one.two', {
url: '/two',
template: '<p>this is state one-two</p>',
})
.state('three', {
url: '/three',
template: '<p>this is state three</p>',
})
});
ใน html ทำการกำหนด link ไปยัง state ต่างๆ
<div class="container"> <ul class="nav nav-pills"> <li><a ui-sref="one">State One</a></li> <li><a ui-sref="one.two">State Two</a></li> <li><a ui-sref="three">State Three</a></li> </ul> <div> <p>Next of this line is ui-view</p> <div ui-view></div> </div> </div>
เพิ่มฟังก์ชั่น onEnter และ onExit ให้กับแต่ละ state
.state('one', {
url: '/one',
template: '<p>this is state one</p><p ui-view></p>',
onEnter: function () {
console.log("[onEnter]State One onEnter");
},
onExit: function () {
console.log("[onExit]State One onExit");
},
controller: function () {
console.log("[controller]State One Controller");
}
})
.state('one.two', {
url: '/two',
template: '<p>this is state one-two</p>',
onEnter: function () {
console.log("[onEnter] State One.Two onEnter");
},
onExit: function () {
console.log("[onExit] State One.Two onExit");
}
})
.state('three', {
url: '/three',
template: '<p>this is state three</p>',
onEnter: function () {
console.log("[onEnter] State Three onEnter");
},
onExit: function () {
console.log("[onExit] State Three onExit");
},
controller: function () {
console.log("[controller] State Three Controller");
}
});
เพิ่มข้อความแสดงใน log โดยกำหนด Event ใน $rootScope
angular.module('application', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
...
})
.run(function ($state, $rootScope) {
// State Change Event
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
console.log("[$stateChangeStart] From: ", (fromState.name) ? fromState.name: "No State", "To: ", toState.name);
});
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log("[$stateChangeSuccess] From: ", (fromState.name) ? fromState.name: "No State", "To: ", toState.name);
});
// View Loading Event
$rootScope.$on('$viewContentLoading', function (event, viewConfig) {
console.log("[$viewContentLoading] View Loading...");
});
$rootScope.$on('$viewContentLoaded', function (event) {
console.log("[$viewContentLoaded] Loaded Complete");
});
});
สามารถดูตัวอย่างผลลัพธ์ได้ที่นี่ Demo
สังเกตได้ว่า เมื่อมีการเปลี่ยนแปลง state จะมีการทำงานของ stateChange Event และ viewLoad Event
โดยจะทำ stateChange Event ก่อน viewLoad Event
