รู้จักกับ resolve ใน state

resolve เป็น property ที่อยู่ใน state ใช้สำหรับเตรียมข้อมูลก่อนที่จะมาใช้ใน controller ของ state

โดยภายใน resolve จะทำงานให้เสร็จก่อนเริ่ม controller

resolve จะทำการ map ข้อมูลดังนี้

  • key - เป็นชื่อตัวแปรที่จะเรียกใช้ใน controller
  • factory - เป็นฟังก์ชั่นที่ทำการ return ข้อมูลมา ซึ่งในกรณีที่ค่านั้นเป็น promise จะถูกทำให้ resolved ก่อนที่จะส่งค่าให้ controller

ซึ่งมีรายละเอียดดังนี้

angular.module('application', ['ui-router'])
	.config(function ($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('stateName', {
				url: 'url',
				template: '<p>this is part of stateName</p>', //or templateUrl: 'someFile.html'
				resolve: {
					simpleObj: function () {
						return {
							value: 'data'
						}
					},
					promiseObj: function ($http) {
						return $http({method: 'GET', url:'/someUrl'})
							.then(function (response) {
								return doSomething(response.data);
							});
					}
				},
				controller: function ($scope, simpleObj, promiseObj) {
					$scope.value = simpleObj.value;
					$scope.promise = promiseObj;
				}
			});
	});

ข้อดีของ resolve คือ กรณีที่ controller ต้องการนำข้อมูลที่มาจากแต่ละที่มาประมวลผลรวมกัน โดย resolve จะทำให้ทำการแตก thread และทำการดึงข้อมูลพร้อมๆกันได้ ข้อมูลจะถูกเตรียมเสร็จเรียบร้อยก่อนเริ่มใช้งาน controller

รู้จักกับ data

data เป็น property ที่อยู่ใน state ใช้สำหรับกำหนดข้อมูลต่างๆไว้ในแต่ละ state

โดยจะสามารถเรียกใช้งาน data ได้โดยผ่าน $state

ซึ่งมีรายละเอียดดังนี้

angular.module('application', ['ui-router'])
	.config(function ($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('stateName', {
				url: 'url',
				template: '<p>this is part of stateName</p>', //or templateUrl: 'someFile.html'
				data: {
					customData1: 1,
					customData2: "some text"
				},
				controller: function ($scope, $state) {
					// $state.current is mean current state
					$scope.data1 = $state.current.data.customData1;
					$scope.promise = $state.current.data.customData1;
				}
			});
	});

เมื่อไหร่ถึงเลือกใช้ resolve เมื่อไหร่ถึงเลือกใช้ data

เราจะเลือกใช้ resolve สำหรับค่าที่มีการเปลี่ยนแปลงได้ หรือข้อมูลที่ทำการเรียกใช้งานจาก service ต่างๆ

เราจะเลือกใช้ data ในกรณีที่ต้องการใช้ค่าที่เป็น constant ต่างๆในแต่ละ state เช่น error message

เราจะทำการดึงลิสต์ข้อมูลมาแสดงผลใน state contact โดยใช้ resolve

และนำข้อความมาแสดงผลโดยใช้ data

เพิ่มข้อมูลรายชื่อ contact

ในไฟล์ js ทำการกำหนด state contact ดังนี้

angular.module('application', ['ui.router'])
	.config(function ($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('home', {
				url: '/home',
				template: '<p>this is part of home</p>'
			})
			.state('contact', {
				url: '/contact',
				template: '<h3>This is Contact</h3>' +
					'<ul>' + '<li ng-repeat="contact in contacts">' +
					'{{contact.name}}' + '(Age: {{contact.age}}) ' + 
					'E-Mail: {{contact.email}}</li></ul>'
			})
			.state('about', {
				url: '/about',
				template: '<p>Creator is {{name}}</p>',
				controller: function ($scope) {
					$scope.name = "Google!!";
				}
			});
	});

เพิ่มส่วนที่เรียกใช้ข้อมูลจาก resolve และ controller เพื่อเรียกใช้ข้อมูล

โดยข้อมูลจะถูกเก็บไว้ใน contacts.json

angular.module('application', ['ui.router'])
	.config(function ($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('home', {
				url: '/home',
				template: '<p>this is part of home</p>'
			})
			.state('contact', {
				url: '/contact',
				template: '<h3>This is Contact</h3>' +
					'<ul>' + '<li ng-repeat="contact in contacts">' +
					'{{contact.name}}' + '(Age: {{contact.age}}) ' + 
					'E-Mail: {{contact.email}}</li></ul>',
				resolve: {
					contacts: function ($http) {
						return $http({method: 'GET', url: 'contacts.json'})
							.then(function (response) {
								return response.data;
							});
					}
				},
				controller: function ($scope, contacts) {
					$scope.contacts = contacts;
				}
			})
			.state('about', {
				url: '/about',
				template: '<p>Creator is {{name}}</p>',
				controller: function ($scope) {
					$scope.name = "Google!!";
				}
			});
	});

ในไฟล์ html เพิ่มเมนูต่อจาก home ชื่อ contact

<div class="container">
	<ul class="nav nav-pills">
		<li><a ui-sref="home">Home</a></li>
		<li><a ui-sref="about">about</a></li>
		<li><a ui-sref="contact">contact</a></li>
	</ul>
	<div>
		<p>Next of this line is ui-view</p>
		<div ui-view></div>
	</div>
</div>

เพิ่ม message แสดงเวลาเข้าหน้า home

ทำการเพิ่ม message โดยใช้ data ระบุ message เป็น "Welcome Home" และเรียกใช้ใน controller ดังนี้

angular.module('application', ['ui.router'])
	.config(function ($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('home', {
				url: '/home',
				template: '<p>this is part of home</p>',
				data: {
					message: "Welcome Home"
				},
				controller: function ($state) {
					alert($state.current.data.message);
				}
			})
			.state('contact', {
				url: '/contact',
				template: '<h3>This is Contact</h3>' +
					'<ul>' + '<li ng-repeat="contact in contacts">' +
					'{{contact.name}}' + '(Age: {{contact.age}}) ' + 
					'E-Mail: {{contact.email}}</li></ul>',
				resolve: {
					contacts: function ($http) {
						return $http({method: 'GET', url: 'contacts.json'})
							.then(function (response) {
								return response.data;
							});
					}
				},
				controller: function ($scope, contacts) {
					$scope.contacts = contacts;
				}
			})
			.state('about', {
				url: '/about',
				template: '<p>Creator is {{name}}</p>',
				controller: function ($scope) {
					$scope.name = "Google!!";
				}
			});
	});

สามารถดูตัวอย่างผลลัพธ์ได้ที่นี่ Demo