ใน Directive จะสามารถทำการกำหนดฟังก์ชั่นและข้อมูลต่างๆได้ โดยใช้ Controller ภายใน Directive ได้

การใช้ Controller ใน Directive

ในการใช้ Controller ใน Directive จะต้องมีการกำหนด Property controller ให้กับ Directive ซึ่งวิธีการใช้งานจะเหมือนกับ Controller ปกติเลย

และสามารถกำหนด Alias ให้กับ Controller ได้โดยใช้ Property controllerAs

angular.directive('someDirective', function () {
	return {
		restrict: 'A',
		controller: function ($scope) {
			...
		},
		controllerAs: 'someController'
	};
});				

ทดสอบความเข้าใจเกี่ยวกับ Scope ของ Controller ใน Directive

ทำการสร้าง Directive ชื่อว่า dadDirective โดยมีโครงสร้างดังนี้

angular.directive('dadDirective', function () {
	return {
		restrict: 'E',
		template: '<div>'+
			'<ul><li>this.message is \{\{dad.message}}</li>' +
			'<li>scope.message is \{\{message}} </li></ul></div>',
		controller: function ($scope) {
			$scope.message = "[ScopeDad Data]";
			this.message = '[Dad Data]';
		},
		controllerAs: 'dad'
	};
});

เรียกใช้ <dad-directive> ใน html

<dad-directive></dad-directive>

จะได้ผลลัพธ์ดังนี้

  • this.message is [Dad Data]
  • scope.message is [ScopeDad Data]

สร้าง Directive เพิ่มชื่อ sonDirective

angular.directive('dadDirective', function () {
		...
	})
	.directive('sonDirective', function () {
		return {
			restrict: 'E',
			template: '<ul><li>this.message is \{\{son.message}}</li>' +
			'<li>scope.message is \{\{message}} </li></ul>',
			controller: function ($scope) {
				$scope.message = "[ScopeSon Data]";
				this.message = '[Son Data]';
			},
			controllerAs: 'son'
		};
	});

เพิ่ม <son-directive> ในส่วนของ template ของ dadDirective

angular.directive('dadDirective', function () {
		return {
			restrict: 'E',
			template: '<div>'+
				'<ul><li>this.message is \{\{dad.message}}</li>' +
				'<li>scope.message is \{\{message}} </li>'+
				'<li><son-directive></son-directive></li></ul></div>',
			controller: function ($scope) {
				$scope.message = "[ScopeDad Data]";
				this.message = '[Son Data]';
			},
			controllerAs: 'dad'
		};
	})
	.directive('sonDirective', function () {
		...
	});

เมื่อทำการเรียกใช้จะได้ผลลัพธ์ดังนี้

  • this.message is [Dad Data]
  • scope.message is [ScopeSon Data]
    • this.message is [Son Data]
    • scope.message is [ScopeSon Data]

สังเกตได้ว่า ค่าของ $scope.message มีค่า เป็น [ScopeSon Data] ของ son

แสดงว่าเมื่อกำหนดตัวแปรด้วย $scope ตัวแปรจะเป็นตัวแปรเดียวกัน

Scope ของ Controller ใน Directive

จากที่เราเคยได้ลองเรียกใช้ตัวแปรนอก ng-controller พบว่าไม่สามารถใช้ได้

เราจะมาลองทำการสลับตัวแปรของ dad.message และ son.message ดู

angular.directive('dadDirective', function () {
		return {
			restrict: 'E',
			template: '<div>'+
				'<ul><li>son.message is \{\{son.message}}</li>' +
				'<li>scope.message is \{\{message}} </li>'+
				'<li><son-directive></son-directive></li></ul></div>',
			controller: function ($scope) {
				$scope.message = "[ScopeDad Data]";
				this.message = '[Dad Data]';
			},
			controllerAs: 'dad'
		};
	})
	.directive('sonDirective', function () {
		return {
			restrict: 'E',
			template: '<ul><li>dad.message is \{\{dad.message}}</li>' +
			'<li>scope.message is \{\{message}} </li></ul>',
			controller: function ($scope) {
				$scope.message = "[ScopeSon Data]";
				this.message = '[Son Data]';
			},
			controllerAs: 'son'
		};
	});

เมื่อทำการเรียกใช้จะได้ผลลัพธ์ดังนี้

  • son.message is [Son Data]
  • scope.message is [ScopeSon Data]
    • dad.message is [Dad Data]
    • scope.message is [ScopeSon Data]

สังเกตได้ว่า controller ที่อยู่ใน directive ไม่จำเป็นที่จะต้องอยู่ใน tag ที่ directive นั้นอยู่

ข้อควรระวัง

ลองทำการกำหนดให้ ชื่อของ controllerAs เป็นชื่อเดียวกัน

angular.directive('dadDirective', function () {
		return {
			restrict: 'E',
			template: '<div>'+
				'<ul><li>dad.message is \{\{same.message}}</li>' +
				'<li>scope.message is \{\{message}} </li>'+
				'<li><son-directive></son-directive></li></ul></div>',
			controller: function ($scope) {
				$scope.message = "[ScopeDad Data]";
				this.message = '[Dad Data]';
			},
			controllerAs: 'same'
		};
	})
	.directive('sonDirective', function () {
		return {
			restrict: 'E',
			template: '<ul><li>son.message is \{\{same.message}}</li>' +
			'<li>scope.message is \{\{message}} </li></ul>',
			controller: function ($scope) {
				$scope.message = "[ScopeSon Data]";
				this.message = '[Son Data]';
			},
			controllerAs: 'same'
		};
	});

จะได้ผลลัพธ์ดังนี้

  • dad.message is [Son Data]
  • scope.message is [ScopeSon Data]
    • son.message is [Son Data]
    • scope.message is [ScopeSon Data]

สังเกตได้ว่า ไม่ควรใช้ชื่อ controllerAs ตัวเดียวกันเนื่องจาก AngularJS จะมองเห็นเป็นตัวแปรใน controller เดียวกัน

กรณีใช้งานข้าม Module กัน

ลองทำการเรียกใช้ Directive ข้าม Module กัน

โดยเพิ่ม Dependency Injection ให้กับ module application

angular.module('application' , ['application.son'])
	.directive('dadDirective', function () {
		return {
			restrict: 'E',
			template: '<div>'+
				'<ul><li>son.message is \{\{son.message}}</li>' +
				'<li>scope.message is \{\{message}} </li>'+
				'<li><son-directive></son-directive></li></ul></div>',
			controller: function ($scope) {
				$scope.message = "[ScopeDad Data]";
				this.message = '[Dad Data]';
			},
			controllerAs: 'dad'
		};
	})
angular.module('application.son', []).directive('sonDirective', function () {
		return {
			restrict: 'E',
			template: '<ul><li>dad.message is \{\{dad.message}}</li>' +
			'<li>scope.message is \{\{message}} </li></ul>',
			controller: function ($scope) {
				$scope.message = "[ScopeSon Data]";
				this.message = '[Son Data]';
			},
			controllerAs: 'son'
		};
	});

จะได้ผลลัพธ์ดังนี้

แสดงว่าการใช้งานข้ามโมดูลก็สามารถใช้งานตัวแปรได้