Sử dụng scope trong Directive
Như chúng ta đã biết, Scope trong angularJS là một object (đối tượng) có nhiệm vụ giao tiếp dữ liệu giữa controller và view của ứng dụng, scope được dùng trong hầu hết các thành phần của AngularJS như controller, routes, services... và trong bài này chúng ta sẽ tìm hiểu về việc sử dụng scope trong ...
Như chúng ta đã biết, Scope trong angularJS là một object (đối tượng) có nhiệm vụ giao tiếp dữ liệu giữa controller và view của ứng dụng, scope được dùng trong hầu hết các thành phần của AngularJS như controller, routes, services... và trong bài này chúng ta sẽ tìm hiểu về việc sử dụng scope trong directive.
1, Scope trong Directives
Scope đều được sử dụng trong mỗi directives, chúng có nhiệm vụ giúp truy cập các data/method trong template và link funtion của controllers. mà các directives sẽ sử dụng luôn các parent scope và sẽ không tự tạo scope(thường là sử dụng scope của controller).
Chúng ta cũng có thể thay đổi scope mặc định của các directives bằng cách truyền một DDO(directive definition object) object
var app = angular.module("myTest",[]); app.directive("myDirective",function(){ return { restrict: "EA", scope: false, link: function(){ ... } } });
2. Các loại Scope trong Directives
2.1 Scope: false ( directive sẽ sử dụng và đồng bộ với parent scope)
Để hiểu rõ hơn chúng ta cùng xem vi dụ sau:
<div ng-app="myTest"> <div ng-controller="myController"> <h2 ng-click="reverseName()">{{name}}, Click vao toi de dao nguoc ten</h2> <div my-directive class='directive'></div> </div> </div>
var app = angular.module("myTest",[]); app.controller("myController",function($scope){ $scope.name = "angularJS"; $scope.reverseName = function(){ $scope.name = $scope.name.split(').reverse().join('); }; }); app.directive("myDirective", function(){ return { restrict: "EA", scope: false, template: "<div>Ten ban la : {{name}}</div>"+ "Change your name : <input type='text' ng-model='name' />" }; });
demo: https://jsfiddle.net/huannd/euk9uaaL/
Nếu như chúng ta thay đổi thông tin name bên trong textbox, thì header cũng bị thay đổi theo. Bởi vì không có scope trong DDO, Directive sẽ sử dụng parent scope. Do vậy bất cứ sự thay đổi nào bên trong directive nó cũng thay đổi parent scope hoặc ngược lại.
2.2 Scope: true. (Directive sẽ tạo một scope mới)
Để một Directive tự có một scope của chính nó, chúng ta phải gán giá trị true cho scope bên trong DDO, khi scope được gắn giá trị true AngularJS sẽ tạo ra một scope mới và gán lại cho directive, scope mới này được tạo ra và kế thừa từ parent scope.
Ví dụ: Vẫn là ví dụ trên nhưng ta thay đổi giá trị scope từ false sang true trong file javascript
app.directive("myDirective", function(){ return { restrict: "EA", scope: false, template: "<div>Ten ban la : {{name}}</div>"+ "Change your name : <input type='text' ng-model='name' />" }; });
demo: https://jsfiddle.net/huannd/rwx7yduy/
Thao tác trên demo chúng ta có thể thấy, khi chúng ta click vào header để đảo ngược tên, thì tên sẽ được đảo ngược trên cả header và bên trong template text box. nhưng khi chúng ta thay đôi name trong text box thì thông tin name trên header không thay đổi.
Vậy sự khác nhau giữa scope: true và scope: false là gì?
- Khi scope được gán là true AngularJS sẽ tạo một scope mới bằng cách kế thừa parent scope ( thông thường là controller scope, ngoài ra là rootScope). Bất cứ sự thay đổi nào của parent scope cũng kéo theo sự thay đổi của scope mới trong directive và Bất cứ sự thay đổi nào của new scope trong directive sẽ không ảnh hưởng tới parent scope. chú ý là khi chúng ta đã thay đổi thông tin scope trong directive thì bất kì sự thay đổi nào của parent scope cũng sẽ không ảnh hưởng đến scope trong directive.
- Khi scope được gán là false, Controller và Directive dùng chung một scope object do đó bất cứ sự thay đổi nào 1 trong 2 scope cũng sẽ kéo theo sự thay đổi của scope còn lại. hay nói cách khác chúng đồng bộ với nhau.
2.3 Scope: {} (Directives lấy một scope isolated mới) Scope được viết như sau:
var app = angular.module("myTest",[]); app.directive("myDirective",function(){ return { restrict: "EA", scope: {}, link: function(){ ... } } });
Gán một Object cho scope bên trong DDO, Angular sẽ tạo ra một scope mới cho directive nhưng scope này không kế thừa từ parent scope. Nó là scope mới hoàn toàn và được gọi là Isolate scope.
Khi tạo một custom directive thì chúng ta nên sử dụng cách này bởi vì cách này sẽ đảm bảo directive có thể dùng ở mọi nơi bên trong ứng dụng. Các parent scope sẽ không thể can thiệp vào bên trong directive scope và AngularJS còn cho phép Isolate scope có thể giao tiếp với các parent scope thông một vài ký tự đặc biệt như @, =, &. Bởi vì trong một vài tình huống đặc biệt directive scope cần trao đổi dữ liệu với parent scope.
Một Isolate scope bên trong directive bằng một object, và có các thuộc tính name, color, reverse với các ký tự đặc biệt dùng để liên kết với parent scope.
scope: { name: "@", color: "=", reverse: "&" }
- @: Prefix @ là kiểu one-way binding giữa directive scope và parent scope, nghĩa là bất cứ sự thay đổi nào của parent scope cũng kéo theo sự thay đổi của directive scope. Nhưng không có chiều ngược lại.
- =: Là kiểu two-way binding giữa parent scope và directive scope. Nghĩa là bất sự thay đổi nào của 1 trong 2 scope cũng ảnh hưởng tới scope còn lại.
- &: Là kiểu method binding, được sử dụng để bind tất cả các phương thức từ parent scope sang directive, Nó hữu ích trong trường hợp directive cần phải thực thi callback của parent scope.