ถึงเราจะคุ้นเคยกับการใช้งาน scope ในหลายๆ ตัวอย่างที่ผ่านมาแล้ว
แต่อาจจะยังไม่เข้าใจละเอียดมากนัก เนื้อหาตอนนี้ เลยจะมาอธิบายเพิ่มเติม
ตามความเข้าใจของผู้เขียนบทความ
อ้างอิงจาก https://docs.angularjs.org/guide/scope
ใน angularjs จะสามารถเรียกใช้งาน scope ได้อยู่ 2 ส่วน คือ
1. ส่วนที่กำหนดจาก ngApp จะเป็น $rootScope
2. ส่วนกำหนด ใน controller โดยใช้ ngController จะเป็น $scope
โดย angularjs จะใช้วิธีกำหนด css class ชื่อว่า ng-scope
ไว้ในทั้งสองส่วน เช่น
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!DOCTYPE html> < html ng-app> < head > < meta charset = "UTF-8" > < script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js" ></ script > < title >Document</ title > </ head > < body > < div class = "container" > < label >Name:</ label > < input type = "text" ng-model = "yourName" placeholder = "Enter a name here" > < hr > < h1 >Hello {{yourName}}!</ h1 > </ div > </ body > </ html > |
หมายเหตุ: ใน html หรือ directive ที่กำหนดเอง จะใช้รูปแบบ แบบ spinal-case
เช่น ng-app หรือ ng-controller คล้ายรุปแบบกระดูสันหลัง |-|-|-|-|-|
ส่วนการอ้างอิง จะใช้วิธีเรียกแบบ camelCase หรือหลังอูฐ เช่น ngApp ngController
จากโค้ดด้านบน
ส่วน html แท็กเปิด จะมีการกำหนด css class เข้าไป
1 | < html ng-app = "" class = "ng-scope" > |
เนื่องจากตัวอย่างด้านบน ไม่มีการกำหนด ในส่วนของ controller
ดังนั้นค่าตัวแปรต่างที่เรียกใช้ จะเป็นในส่วนของ $rootScope
ส่วนที่มีการกำหนด expression
1 | < h1 >Hello {{yourName}}!</ h1 > |
แท็ก h1 จะถุกกำหนด css class ชื่อ ng-binding จะได้เป้น
1 | < h1 class = "ng-binding" >Hello !</ h1 > |
ngApp ไม่จำเป็นต้องกำหนดในส่วนแท็กเปิด html สามารถกำหนดในส่วนของแท็กเปิด body
1 | < body ng-app> |
หรืออื่นๆ ก็ได้ ในหนึ่งไฟล์สามารถมีได้หลายที่ แต่โดยทั่วไปแล้ว
จะกำหนด ที่เดียว และไว้ในส่วนของ แท้กเปิด html
หากมีการกำหนด controller จะต้องมีการเรียกใช้งาน angular.module และกำหนด
ค่าต่างๆ ให้กับ controller ไม่เช่นนั้น ส่วนของ controller ก็จะไม่ทำงาน
โดยจะต้องกำหนดชื่อในกับ ngApp เพื่อใช้ในการสร้าง module ด้วย
เช่น
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!DOCTYPE html> <!--กำหนดชื่อให้กับ ngApp--> < html ng-app = "app" > < head > < meta charset = "UTF-8" > < script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js" ></ script > < title >Document</ title > </ head > < body > <!-- เมื่อมีการใช้งาน controller--> < div class = "container" ng-controller = "myCtrl" > < label >Name:</ label > < input type = "text" ng-model = "yourName" placeholder = "Enter a name here" > < hr > < h1 >Hello {{yourName}}!</ h1 > </ div > < script type = "text/javascript" > angular.module('app',[]) .controller('myCtrl',['$scope',function($scope){ }]); </ script > </ body > </ html > |
จากโค้ดตัวอย่างด้านบน จะมีการกำหนด controller ดังนั้น angularjs จะทำการกำหนด
css class ชื่อ ng-scope เข้าไปในส่วนของแท็ก div
1 | < div class = "container" ng-controller = "myCtrl" > |
จะได้เป็น
1 | < div class = "container ng-scope" ng-controller = "myCtrl" > |
เราสามารถเรียกใช้งาน $rootScope และ $scope โดยการ inject ค่าเข้าไปใน
controller จากโค้ดเป้นการใช้งาน $scope และมีการ inject ค่า $scope เข้าไป
ใน controller
1 2 3 4 5 6 | <script type= "text/javascript" > angular.module( 'app' ,[]) .controller( 'myCtrl' ,[ '$scope' , function ($scope){ }]); </script> |
หากต้องการเรียกใช้งาน $rootScope สามารถทำได้ดังนี้
1 2 3 4 5 6 | <script type= "text/javascript" > angular.module( 'app' ,[]) .controller( 'myCtrl' ,[ '$scope' , '$rootScope' , function ($scope,$rootScope){ }]); </script> |
$scope จะเป็น child หรือลูกของ $rootScope
ถ้าเปรียบคือ
$rootScope เป็น parent
$scope เป็น child
และเนื่องจาก $rootScope ที่สามารถสืบทอดคุณสมบัติได้ หรือที่เรียกว่า Inheritance
ดังนั่ง property หรือ medthod ที่กำหนด จาก $rootScope ก็จะสามารถเรียกใช้งาน
ใน controller ได้
ดูโค้ดประกอบอธิบาย
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!DOCTYPE html> <!--กำหนดชื่อให้กับ ngApp--> < html ng-app = "app" > < head > < meta charset = "UTF-8" > < script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js" ></ script > < title >Document</ title > </ head > < body > <!-- yourName อยู่นอก controller จะไม่สามารถใช้ค่าที่กำหนดจาก scope ใน controller ได้ แต่ สามารถใช้ค่า ที่กำหนดจาก parent ของ $scope หรือ $rootScope --> < p >Hi {{yourName}}</ p > <!-- เมื่อมีการใช้งาน controller--> < div class = "container" ng-controller = "myCtrl" > < label >Name:</ label > < input type = "text" ng-model = "yourName" placeholder = "Enter a name here" > < hr > <!-- yourName ที่กำหนด ใน controller สามารถใช้ค่า ที่กำหนดจาก parent ของ scope หรือ $rootScope--> < h1 >Hello {{yourName}}!</ h1 > </ div > < script type = "text/javascript" > angular.module('app',[]) .controller('myCtrl',['$scope','$rootScope',function($scope,$rootScope){ $rootScope.yourName="demo1"; }]); </ script > </ body > </ html > |
จากโค้ดด้านบน จะเห็นว่า ค่า yourName ทั้งในและนอก controller จะมีค่าเท่ากับ demo1
นั้นก็เพราะ $scope สืบทอดค่ามาจาก $rootScope
ทีนี้มาดูกันว่า กลับกัน ค่าที่กำหนดด้วย child หรือ $scope จะไม่สามารถเรียกใช้ นอก controller ได้
ดูโค้ดประกอบ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <!DOCTYPE html> <!--กำหนดชื่อให้กับ ngApp--> < html ng-app = "app" > < head > < meta charset = "UTF-8" > < script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js" ></ script > < title >Document</ title > </ head > < body > <!-- yourName อยู่นอก controller จะไม่สามารถใช้ค่าที่กำหนดจาก scope ใน controller ได้ แต่ สามารถใช้ค่า ที่กำหนดจาก parent ของ scope หรือ rootScope --> < p >Hi {{yourName}}</ p > <!-- เมื่อมีการใช้งาน controller--> < div class = "container" ng-controller = "myCtrl" > < label >Name:</ label > < input type = "text" ng-model = "yourName" placeholder = "Enter a name here" > < hr > <!-- yourName ที่กำหนด ใน controller สามารถใช้ค่า ที่กำหนดจาก parent ของ scope หรือ $rootScope แต่หากมีการกำหนดค่า ของ $scope ใน controller ค่าที่ได้ จะใช้ค่าของ $scope แทนค่าจาก $rootScope --> < h1 >Hello {{yourName}}!</ h1 > </ div > < script type = "text/javascript" > angular.module('app',[]) .controller('myCtrl',['$scope','$rootScope',function($scope,$rootScope){ $scope.yourName="demo2"; }]); </ script > </ body > </ html > |
ใน controller มีการกำหนดค่า yourName ด้วย $scope ซึ่งเป็น child ของ $rootScope
ดังนั้นจะทำให้ yourName ที่อยู่นอก controller จะเป็น undefined
ส่วน yourName ใน controller จะมีค่าเท่ากับ demo2
สรุปอย่างง่าย:
1. ค่าที่กำหนดจาก $rootScope สามารถใช้งาน ใน controller ใดๆ ก็ได้
2. ถ้าใน controller มีการกำหนด $rootScope และ $scope โดยมีชื่อ หรือ property เดียวกัน เช่น
1 2 | $rootScope.yourname= "demo1" ; $scope.yourname= "demo2" ; |
แบบนี้ expression ใน controller จะใช้ค่าจาก $scope ซึ่งเท่ากับ demo2
ส่วน expression นอก controller จะใช้ค่าจาก $rootScope ซึ่งเท่ากับ demo1
3. ค่าที่กำหนดจาก $scope จะใช้ได้เฉพาะใน controller นั้นๆ เท่านั้น
ขอต่อรายละเอียดเกี่ยวกับ scope ในตอนหน้า รอติดตาม