Angular JS Directive vs Component

96f2d39ed138258a1d4c5e638e1d707cab035b1a.png

Directive

Một trong những điều thú vị khi làm việc với Angular JS đó là việc sử dụng directive. Thư viện AngularJS cung cấp một số directive có sẵn. Ngoài ra, chúng ta cũng có thể tự mình định nghĩa thêm các directive sử dụng trong ứng dụng. AngularJS directive giúp cho chúng ta mở rộng khả năng của ngôn ngữ HTML hay nói cách khác là nó giúp cho những dev như chúng ta làm cho HTML mạnh thêm. Ví dụ đơn giản thế này:

Dưới đây là cuộc đối thoại giữa dev và customer

  • Customer (có chút hiểu biết về HTML): Tao muốn nội dung thẻ span này viết hoa chữ cái đầu của mỗi từ, còn từ cuối cùng và từ đầu tiên thì viết hoa tất cả chữ (VD: MÌNH Thích Thì Mình Làm THÔI)
  • Dev: OK dễ thôi, mở code ra sửa lại là được
  • Customer: Nhưng tao muốn trong code thì vẫn viết như bình thường (mình thích thì mình làm thôi), chỉ khi nào hiện lên trình duyệt thì mới định dạng như thế kia.
  • Dev: đậu xanh..
  • Customer (chém bay nóc nhà tiếp): À chỉ span nào được chỉ định thì mới định dạng như vậy, còn không thì hiển thị như bình thường nhé
  • Dev: @&@$(^@!!

OK, giải pháp có thể chấp nhận được là, gán cho thẻ span cần định dạng 1 class ví dụ là class="need-to-format" chẳng hạn và dùng jQuery để lấy các span có class need-to-format rồi xử lý:

<span class="need-to-format">minh thich thi minh lam thoi</span>

Giá như có 1 element nào đó mà chỉ cần sử dụng nó cùng nội dung trong attribute là sẽ đươc định dạng như mong muốn giống như đoạn code bên dưới:

<need-to-format txt="minh thich thi minh lam thoi"></need-to-format>

Chỉ cần sử dụng element need-to-format là có kết quả định dạng như mong muốn, trong trường hợp như vậy, Angular JS có thể giúp chúng ta thực hiện điều này bằng cách sử dụng directive.

Tạo directive

Bước 1: Tạo controller. đặt nó vào file controllers.js

angular.module('DemoApp', []).controller('DemoCtrl', function ($scope) {

});

Bước 2: Thêm directive format lại nội dung như yêu cầu của KH. Viết trong file directive.js

angular.module('DemoApp').directive('needToFormat', function () {
    return {
        restrict: 'E',
        link: function (scope, elem, attrs) {
          scope.formatTxt = function(txt) {
            arr = txt.replace(/\b\w/g, l => l.toUpperCase()).split(' ');
            arr[0] = arr[0].toUpperCase();
            arr[arr.length - 1] = arr[arr.length - 1].toUpperCase();
            return arr.join(' ');
          };
        },
        scope: {
          txt: '@'
        },
        templateUrl: 'template.html'
     }
});

Bước 3: Tạo template cho directive trong file template.html

<p>{{formatTxt(txt)}}</p>

Bước 4: Một đoạn html để test

<!DOCTYPE html>
<html ng-app="DemoApp">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />
  <title></title>
</head>
<body>
  <div ng-controller="DemoCtrl">
    <need-to-format txt="mình thích thì mình làm thôi"></need-to-format>
    <br>
    <need-to-format txt="ahjhj đ0^` ng0^k'"></need-to-format>
  </div>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
  <script src="controller.js"></script>
  <script src="directive.js"></script>
</body>
</html>

Component

Từ phiên bản Angular 1.5, một khái niệm mới được đưa vào đó là component. Cách sử dụng component khá giống với directive, nên đôi khi làm dev khá bối rối, không biết nên sử dụng cái nào, trường hợp nào sử dụng component thì tốt hơn trường hợp nào thì không nên,..

Dưới đây ta sẽ cùng tìm hiểu 1 chút về component để từ đó đưa ra sự lựa chọn hợp lý trong từng hoàn cảnh.

Mình sẽ viết lại đoạn code sử dụng directive bên trên theo cách sử dụng component:

*** Tạo 1 component trong file component.js

Componente_component.html',
  controller: function() {
    var _this = this;
    _this.formatTxt = function(txt) {
      arr = txt.replace(/\b\w/g, l => l.toUpperCase()).split(' ');
      arr[0] = arr[0].toUpperCase();
      arr[arr.length - 1] = arr[arr.length - 1].toUpperCase();
      return arr.join(' ');
    };
  }
});

*** tạo template tương ứng cho component ***

<p>{{$ctrl.formatTxt($ctrl.txt)}}</p>

*** Gọi component từ index.html ***

<need-to-format-component txt="I'm a real component"></need-to-format-component>

Như các bạn đã thấy, có một số điểm mà component nhìn vào đơn giản và trực quan hơn như thay vì viết một function chỉ để return object khi khai báo directive thì với component chỉ việc định nghĩa object đó thôi; hay bindToController là default, và controllerAs luôn bật, defaults là $ctrl,..

Ngoài ra một số ưu điểm của Component và khi nào nên sử dụng là

  • Dễ config, trực quan dễ hiểu hơn so với directive
  • Tối ưu cho kiến trúc component-based (Cái này tìm hiểu thêm tại đây)
  • Dễ dàng upgrade lên Angular 2.0

Khi nào ko nên sử dụng Component

  • Vì không có linkcompile function, nên đối với những xử lý cần thực hiện vào thời điểm trước và khi compile thì component không đáp ứng được -> dùng directive
  • Khi muốn component được gọi ra thông qua class name, attribute name thì không đáp ứng được vì component chỉ được gọi ra qua element name -> dùng directive

Dưới đây là bảng so sánh chi tiết hơn giữa componentdirective

f7da879af96452f39cdad542ded447c2.png

KẾT LUẬN

Trên đây mình đã giới thiệu sơ qua về directivecomponent. Mong rằng bài viết phần nào đó giúp các bạn đưa ra quyết định lựa chọn giữa 2 thành phần này một cách hợp lý.

Nguồn tham khảo

  1. https://docs.angularjs.org/guide/component
  2. https://docs.angularjs.org/guide/directive
  3. http://www.codelord.net/2015/12/17/angulars-component-what-is-it-good-for/

All Rights Reserved