0

Can thiệp vào directive trong AngularJS

Giới thiệu về directive

Hầu hết mọi người sử dụng AngularJS đều là directive. Directive làm cho AngularJS trở nên mạnh mẽ hơn. Directive là gốc rễ của AngularJS và làm thế nào để chúng ta (những developer) có thế tương tác với directive

Nếu bạn đã từng sử dụng bất kỳ phần nào trong AngularJS trước đây, tức là bạn đã sử dụng directive, liệu rằng bạn có biết điều này. Bởi vì thuộc tính ng-app là một directive, do đó ng-controller và tất cả những thứ gì có tiền tố ng- đều là directive

<body ng-app>
   <input type="text" ng-model="name" placeholder="name">
   <h1>{{ name }}</h1>
</body>

Khi Angular load một ví dụ đơn giản này, nó sẽ duyệt qua tất cả các phần tử DOM để tìm bất kỳ directive nào có liên quan đến mỗi phần tử DOM. Tất cả những thứ này sẽ được chạy ngầm và chạy một cách tự động.

Để gọi một directive từ HTML, đơn giản chúng ta có thế thực hiện directive trong DOM. Điều đó có nghĩa là, chúng ta chọn một trong bốn phương thức để gọi directive.

Giống như một thuộc tính

<span my-directive></span>

Giống như một class

<span class="my-directive: expression;"></span>

Giống như một element

<my-directive></my-directive>

Giống như một comment

<!-- directive: my-directive expression -->

Tất cả đều giống nhau dưới con mắt của AngularJS. Thực tế, AngularJS sẽ cung cấp cho bạn nhiều lựa chon khác nhau cho các cách gọi directive cùng với tên của tiền tố. Đây là tất cả các cách tương đương nhau:

<input type="text" ng-model="directivename" placeholder="name" />
<span ng-bind="directivename"></span>
<span ng:bind="directivename"></span>
<span ng_bind="directivename"></span>
<span x-ng-bind="directivename"></span>
<span data-ng-bind="directivename"></span>

Hai cách cuổi là các phương thức chỉ được gọi đến trong HTML5 và sẽ vượt qua validator của HTML5

Xây dựng directive đầu tiên

Ở phần giới thiệu trên, chúng ta đã phân tích chi tiết directive hoạt động như thế nào. Bây giờ chúng ta sẽ tạo ra directive đầu tiên của chúng ta.

Directive cơ bản của chúng ta sẽ như sau:

app.directive('ngSparkline', function() {
  return {
    restrict: 'A',
    template: '<div class="sparkline"></div>'
  }
});

Và chúng ta sẽ gọi trong html

<div ng-sparkline></div>

Chú ý rằng khi gọi tên của directive sẽ không giống như tên chúng ta đã định nghĩa là ngSparkline. Mặc dù ví dụ đầu tiên chúng ta chưa làm được nhiều, nhưng đã trình bày được khá nhiều tính năng mạnh mẽ. Bất kỳ đâu trong html của chúng ta, chúng ta cũng có thể thêm thuộc tính ng-sparkline và có các template thêm vào các phần tử DOM.

Có hai cách để tạo ra một directive. Trong ví dụ của chúng ta, chúng ta sẽ xây dựng phương thức trả về một đối tượng mô tả directive. AngularJS trả về những đối tượng hoặc function link khi tạo directive. Xây dựng directive cùng với function link là đã đủ cho một directive đơn giản. Trong hầu hết các phần, chúng ta sẽ tạo ra các directive sử dụng miêu tả đối tượng.

Tùy chọn phạm vi

Trong ví dụ miêu tả đối tượng, chúng ta sẽ thiết lập 2 thành phần. Đầu tiên chúng ta sẽ thiết lập các tùy chỉnh phạm vi. Tùy chỉnh phạm vi được sử dụng để định nghĩa làm thế nào có thể gọi được directive trên các trang.

Như chúng ta đã thấy ở trên, có 4 cách khác nhau để gọi một directive. Do đó sẽ có 4 lựa chọn hợp lệ cho phạm vi.

'A' - <span ng-sparkline></span>
'E' - <ng-sparkline></ng-sparkline>
'C' - <span class="ng-sparkline"></span>
'M' - <!-- directive: ng-sparkline -->

Tùy chọn phậm vi có thể định nghĩa nhiều tùy chọn. Nếu bạn muốn được hỗ trợ nhiều hơn một thành phần hoặc một thuộc tính, đơn giản chỉ cần chắc chắn tất cả các định nghĩa ở trong từ khóa restric

restrict: "EA"

Template

Thứ hai, trong ví dụ của chúng ta, chúng ta đang thiết lập một template. Template là một dòng thông báo nơi chúng ta định nghĩa html sẽ được thêm vào (hoặc được thay thế, chúng ta chỉ nói điều này trong phần nhỏ của nội dung). Điều này đặc biệt có tác dụng khi chúng ta muốn chia sẻ các directive thông qua app và bạn chỉ muốn thông qua một file duy nhất.

TemplateUrl

Nếu bạn muốn tải một template thông qua ajax, bạn có thể định nghĩa tùy chỉnh templateUrl, như vậy sẽ sử dụng ajax để gọi đến template.

templateUrl: 'templates/ng-sparkline-template.html'

Cùng với đó, chúng ta có thể bắt đầu thêm các chức năng. Trước khi chúng ta có thể thực hiện được điều này, chúng ta cần phải biết làm thế nào directive có thể khởi tạo trong DOM.

Làm thế nào directive được sinh ra (compile và instantiation)

Sau khi DOM được load xong thì tiến trình AngularJS bắt đầu khởi động, quá trình đầu tiên xảy ra là HTML được phân tách bởi trình duyệt như một cây DOM. Sau đó cây này được phân tích bằng phương thức $compile() của AngularJS. $compile() sẽ chạy qua cây DOM và tìm kiếm các directive được khai báo cho các phần tử DOM khác nhau. Khi tất cả các directive khai báo đã được tìm thấy từ các phần tử DOM thì sẽ được sắp xếp theo độ ưu tiên, hàm compile sẽ được chạy và trả về một function link().

Tùy chọn bắt buộc

Chúng ta sẽ phụ thuộc vào các yêu cầu tùy chọn sau:

app.directive('ngSparkline', function() {
  return {
    restrict: 'A',
    require: '^ngModel',
    scope: {
      ngModel: '='
    },
    template: '<div class="sparkline"><h4>Weather for </h4></div>'
  }
});

Bây giờ chúng ta chỉ gọi directive trên trang này mà không có ng-model, trình duyệt của chúng ta sẽ báo lỗi. Bây giờ để gọi directive, chúng ta phải thêm vào ng-model

<input type="text" ng-model="city" placeholder="Enter a city" />
<div ng-sparkline ng-model="city"></div>

Chú ý: trong các yêu cầu tùy chọn phải có tiền tố ^

Scope

Cũng giống như tất cả các thành phần khác của việc điều khiển AngularJS DOM, những directive có thể trả về scope riêng của mình.

Tùy chọn scope có thể chọn một trong hai tùy chọn khác nhau. Nó có thể thiết lập tùy chọn là true (mặc định không chọn gì là false). Khi scope được xét là true, một scope mới sẽ được tạo ra cho directive. Còn khi scope xét là fasle thì scope sẽ được sử dụng ở nơi gọi directive.

Có 3 loại scope trong directive

  • Local scope property: Ràng buộc giá trị scope với các trị của thuộc tính DOM, sử dụng ký tự @ (hoặc @attr). Bây giờ giá trị của scope bên ngoài sẽ có trong giá trị scope của directive
  • Bi-directional binding: Một ràng buộc dữ liệu có thể thiết lập giữa scope của directive và thuộc tính cha, sử dụng ký tự =(hoặc =attr). Nếu một trong hai thay đổi thì giá trị còn lại cũng thay đổi theo.
  • Parent execution binding: Để thực hiện function trong nội dung của scope cha, chúng ta có thể ràng buộc hàm bằng cách sử dụng ký tự & (hoặc &attr)

Tài liệu tham khảo

http://www.ng-newsletter.com/posts/directives.html


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í