-1

AngularJS directive

I. Directive và một số khái niệm

  • Directive là những "Marker" trong một DOM (các thuộc tính, tên của các element hay CSS class...) và nó được kèm theo một số hành vi đặc biệt hay thậm chí nó còn thay đổi các thành phần DOM hay chính các thành phần con của nó. Angular có một số directive built-in có sẵn như ngBind, ngModelngClass ... ngoài ra bạn cũng có thể tự chế cho mình một directive riêng.
  • Matching Directive: Một element được coi là match với directive nếu directive được khai báo, sử dụng trong html element ví dụ:
<input ng-model="foo">

Input element matches với ngModel

  • Normalization: Angular normalize là một tag hay tên của attribue để xác định được những thành phần nào được match với directive nào. Thông thường chúng ta thường sử dụng camelCase (eg. ngClass, ngModel ..), thế nhưng đối với HTML ta hay dùng dash-delimited attributes ở trên DOM (e.g. ng-model)
  • Normalization process:
    • Cắt bỏ x-, data- của html element/attribute
    • Convert :, -, _ thành camelCase ví dụ
<div ng-controller="Controller">
  Hello <input ng-model='name'> <hr/>
  <span ng-bind="name"></span> <br/>
  <span ng:bind="name"></span> <br/>
  <span ng_bind="name"></span> <br/>
  <span data-ng-bind="name"></span> <br/>
  <span x-ng-bind="name"></span> <br/>
</div>

Tất cả các element trên sẽ được match với ngBind directive

II. Thành phần bên trong directive

II.1 Tạo directive

Cũng giống như controller, directive cũng phải registered với module. Đăng ký directive với cú pháp:

module.directive

Nó sẽ tạo ra một normalized directive và kèm theo một factory function. Factory này trả về một object với nhiều option khác nhau. Và factory fuction này được gọi mỗi khi compiler match với directive ở lần đầu tiên. Chú ý: Khi tạo directive bạn nên tạo ra một directive có tiền tố của riêng bạn để tránh việc xung đột với các thẻ html đặc biệt là không được tạo directive với tiền tố là ng.

II.2 Template

.directive('myCustomer', function() {
  return {
    template: 'Name: {{customer.name}} Address: {{customer.address}}'
  };
})

và trên html sẽ gọi

<div ng-controller="Controller">
  <div my-customer></div>
</div>

Sau khi $compile compile và link tới <div -my-customer> </div>. $compile sẽ tìm và match với directive của những thành phần con, điều đó có nghĩa là bạn có thể tạo ra một directive từ một directive khác. Thông thường nội dung của template lớn thì ta có thể dùng templateUrl rồi link tới một file html

.directive('myCustomer', function() {
  return {
    templateUrl: 'my-customer.html'
  };
});

templateUrl có thể là một function trả về một URL của html. Angular sẽ gọi templateUrl function với 2 tham số. Một là element và attr, là object có liên kết với element đó. Chú ý: Không truy cập được scope từ templateUrl function, do đó template sẽ được yêu cầu trước khi scope được khởi tạo.

.directive('myCustomer', function() {
  return {
    templateUrl: function(elem, attr){
      return 'customer-'+attr.type+'.html';
    }
  };
});

Một chú ý khác đó là khi tạo một directive, nó sẽ được mặc định restricted cho attributes hoặc element. Restrict option: - A: chỉ match với attributes name - E: chỉ match với element name - C: chỉ match với class name - M: chỉ match với comment

.directive('myCustomer', function() {
  return {
    restrict: 'E',
    templateUrl: 'my-customer.html'
  };
});

II.3 Isolating Scope của một Directive

Isolating scope là việc tách biệt scope bên trong directive không còn phụ thuộc vào scope bên ngoài nữa, sau đó sẽ map scope bên ngoài vào scope bên trong directive. Để làm được việc đó thì ta sử dụng option scope bên trong directive.

.directive('myCustomer', function() {
  return {
    restrict: 'E',
    scope: {
      customerInfo: '=info'
    },
    templateUrl: 'my-customer-iso.html'
  };
});
<div ng-controller="Controller">
  <my-customer info="naomi"></my-customer>
  <hr>
  <my-customer info="igor"></my-customer>
</div>

Như đã thấy 2 element trên có attributes info="naomi"info="igor"

scope: {
  customerInfo: '=info'
},

Scope option là một đối tượng có chứa một thuộc tính cho mỗi một isolate scope binding. Như ví dụ trên thifh nó có một thuộc tính - Tên: customerInfo tương ứng với isolae scope property của directive customerInfo - Giá trị: =info cho $compile biết để bind với thuộc tính info

Trong trường hợp tên của attributes trùng với giá trị mà bạn muốn bind ở trong directive scope, có thể dùng cú pháp ngắn gọn sau

...
scope: {
  // same as '=customer'
  customer: '='
},
....

II.4 Directive thao tác với DOM

  • Directive sử dụng link option để thao tác với DOM ( register DOM listener cũng như update DOM). Nó được thực thi sau khi tempate đã được clone
  • linklà một function function link(scope, element, attrs, controller, transcludeFn) { ... } trong đó:
  • scope là một đối Angular scope
  • element là một element mà directive sẽ match
  • attrs là một hash object của normalize attribute name và value
  • controller controller được required bởi directive
link : function(scope, element, attrs){
  element.on('click', function(event) {
  //Update DOM.
    element.html('Thanks for buying this item.');
    element.css({
      color: 'green'
    });
    });
}

Nguồn tham khảo

https://docs.angularjs.org/guide/directive

https://www.sitepoint.com/practical-guide-angularjs-directives-part-two/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí