Scope ของ Directive

ปกติตัวแปรที่อยู่ใน scope ของ Directive จะเชื่อมโยงกันกับ scope ของ Controller ที่มันอยู่ ซึ่งเราสามารถเข้าถึง (access) ได้

ดังนั้นเมื่อมีการกำหนดตัวแปรใน directive เพิ่มเติมแล้ว เกิดกรณีที่ชื่อตัวแปรซ้ำกัน อาจจะทำให้เกิดข้อผิดพลาดได้ (Failure)

โดย AngularJS ได้ทำการกำหนดสิ่งที่เรียกว่า Isolated Scope ขึ้นมา

Isolated Scope คือ อะไร ?

Isolated Scope เป็นการกำหนดขอบเขตของตัวแปรให้อยู่ในแค่ภายใน Directive (Encapsulation)นั้นเท่านั้น

โดยทำการเพิ่ม scope เข้าไปใน directive

angular.directive('', function () {
	return {
		restrict: '',
		scope: {},// Isolated Scope
		template: ''
	};
});

สร้างไฟล์ HTML ชื่อ isolated.html โดยให้ทำการเรียกใช้ CSS และ Javascript ของ Bootstrap3 และ AngularJS

<!DOCTYPE html>
<html ng-app="application">
	<head>
		<!-- Bootstrap CSS -->
		<link rel="stylesheet" href="css/bootstrap.min.css">
		<!-- Bootstrap theme -->
		<link rel="stylesheet" href="css/bootstrap-theme.min.css">
	</head>
	<body ng-controller="demoController as demo">
	<!-- Bootstrap JavaScript -->
	<script src="js/lib/bootstrap.min.js"></script>
	<!--AngularJS Javascript -->
	<script src="js/lib/angular.min.js"></script>
	<script src="js/app.js"></script>
	</body>
</html>

สร้างไฟล์ app.js ที่ใช้ในการเก็บโมดูลต่างๆของ AngularJS

สร้าง Directive ชื่อว่า developer โดยกำหนดให้เป็น Element Directiveและมี template ดังนี้

(function () {
	var app = angular.module("application", []);
	
	app.controller("demoController", function () {
	
	});
	app.directive("developer", function () {
		return {
			restrict: 'E',
			template: '<div><input type="text" ng-model="work" /> work is "\{\{work}}"</div>'
		};
	});
	
})();				

เรียกใช้ Directive ใน html

<body ng-controller="demoController as demo">
	<div><input type="text" ng-model="work">Controller Work is \{\{work}}</div>
	<developer></developer>
	<developer></developer>
	<developer></developer>

จะได้ผลลัพธ์ดังนี้ ลองกรอกข้อมูลดู

Controller Work is {{work}}

สังเกตได้ว่า directive ทุกตัวใช้ ค่าร่วมกัน

ไม่ว่าจะทำการเปลี่ยนแปลงค่าที่ Controller หรือ Directive แต่เนื่องจากใช้ตัวแปรเดียวกัน และอยู่ใน Scope เดียวกันก็จะถูกเปลี่ยนแปลงหมด

เพื่อที่จะให้ข้อมูลของแต่ละ directive เป็นของตังเอง จึงต้องกำหนดให้เป็น isolated scope โดยเพิ่ม scope ใน return ของ directive

app.directive("developer", function () {
	return {
		restrict: 'E',
		scope: {},
		template: '<div><input type="text" ng-model="work" /> work is "\{\{work}}"</div>'
	};
});

จะได้ผลลัพธ์ดังนี้ ลองกรอกข้อมูลดู

Controller Work is {{work}}

สังเกตได้ว่า directive แต่ละตัวมีค่าเป็นของตัวเอง

แล้วเราจะเข้าถึงข้อมูลใน Isolated Scope อย่างไร ?

โดยเราสามารถเข้าถึงข้อมูลใน Isolated Scope ได้ด้วยการนำเข้า (Binding) จากภายนอก ซึ่งมีวิธีการทั้งหมดดังนี้

  • Scope expression (&)
  • Scope Attribute (@)
  • Scope Two way Binding (=)

โดยจะอธิบายทั้งสามประเภทในบทถัดไป