Chỉ thị tùy chỉnh AngularJS: Mẫu, Phạm vi & Transclude

⚡ Tóm tắt thông minh

Các chỉ thị tùy chỉnh trong AngularJS mở rộng HTML với các hành vi có thể tái sử dụng do chính bạn định nghĩa. Một factory chỉ thị trả về một đối tượng định nghĩa, và AngularJS sẽ gắn hành vi đó vào bất cứ nơi nào phần tử, thuộc tính, lớp hoặc chú thích phù hợp xuất hiện trong mã đánh dấu.

  • 🏗️ Đăng ký: Phương thức module.directive nhận một tên đã được chuẩn hóa cộng với một hàm tạo trả về đối tượng định nghĩa directive.
  • 🔤 Đặt tên: Tên được viết theo kiểu camelCase bên trong. JavaScript và kebab-case bên trong HTML, so ngGuru Trên trang đó, nó được viết là ng-guru.
  • 🎯 Kết hợp: Thuộc tính restrict quyết định xem AngularJS có khớp với một phần tử, thuộc tính, lớp hoặc bình luận hay không, và giá trị mặc định là EA.
  • 🧬 Phạm vi truy cập: Một chỉ thị mặc định chia sẻ phạm vi cha, trong khi tùy chọn phạm vi xây dựng một phạm vi biệt lập với các liên kết @, =, & hoặc <.
  • 🔗 Chức năng liên kết: Hàm liên kết nhận các tham số scope, element và attrs, và đây là vị trí thích hợp để đặt các trình lắng nghe DOM và thực hiện việc dọn dẹp.
  • 🧱 Thành phần: Các chỉ thị lồng vào nhau, bao bọc mã đánh dấu tùy ý thông qua cơ chế chèn và cung cấp API cho các chỉ thị cùng cấp thông qua bộ điều khiển.
  • ⚠️ Trạng thái hỗ trợ: AngularJS đã hết hạn hỗ trợ vào ngày 31 tháng 12 năm 2021 và sẽ không nhận được thêm bất kỳ bản vá lỗi hay sửa lỗi bảo mật nào nữa.

Chỉ thị tùy chỉnh trong AngularJS

Chỉ thị tùy chỉnh trong AngularJS là gì?

A Chỉ thị tùy chỉnh Trong AngularJS, `<div>` là một chỉ thị do người dùng định nghĩa, mở rộng HTML với các hành vi do chính bạn viết. Nó được đăng ký trên một `<div>`. mô-đun Sử dụng hàm “directive”, AngularJS sẽ gắn nó vào bất cứ nơi nào phần tử hoặc thuộc tính phù hợp xuất hiện trên trang. Mặc dù AngularJS có rất nhiều tính năng mạnh mẽ, nhưng nó vẫn có thể được tích hợp. chỉ thị tích hợp ngoài khuôn khổ, chẳng hạn như ng-lặp lại, đôi khi cần có chỉ thị tùy chỉnh.

⚠️ Điều chỉnh: Văn bản gốc nói rằng chỉ thị tùy chỉnh "thay thế phần tử mà nó được sử dụng". Theo mặc định thì không: template được chèn vào trong phần tử phù hợp. Nhu cầu thay thế replace: trueĐã bị loại bỏ kể từ AngularJS 1.3.

⚠️ Thông báo hỗ trợ: AngularJS đã đạt đến Hết hạn sử dụng vào ngày 31 tháng 12 năm 2021. và không nhận được thêm bản vá lỗi hoặc bản sửa lỗi bảo mật nào nữa. Mọi thứ bên dưới vẫn chính xác để duy trì mã AngularJS 1.x hiện có; trong Angular hiện đại, các thành phần tương đương là các chỉ thị thuộc tính.

Lý do cần sử dụng chỉ thị tùy chỉnh là do sự lặp lại. Khi cùng một mã đánh dấu hoặc cấu trúc DOM xuất hiện trên nhiều màn hình, chỉ thị sẽ biến nó thành một thẻ có tên duy nhất.

Làm thế nào để tạo một chỉ thị tùy chỉnh?

Hãy cùng xem một ví dụ về cách chúng ta có thể tạo một directive tùy chỉnh trong AngularJS.

Trong trường hợp này, chỉ thị tùy chỉnh đơn giản là sẽ chèn một thẻ div có nội dung "Angular JS Tutorial" vào trang khi chỉ thị được gọi.

Ảnh chụp màn hình có chú thích bên dưới đánh số bốn phần của danh sách được giải thích sau đó.

Tạo chỉ thị tùy chỉnh

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">
    var app = angular.module('DemoApp',[]);
    app.directive('ngGuru',function(){

    return {
        template: '<div>Angular JS Tutorial</div>'
    }
    });

</script>

</body>
</html>

⚠️ Cảnh báo — các lỗi vẫn được giữ nguyên trong danh sách này: Mã được sao chép chính xác như đã công bố. Ba lỗi lặp đi lặp lại trong mọi đoạn mã được liệt kê ở đây: chrset="UTF 8" nên là charset="UTF-8"; angular.jsangular.min.js Cả hai đều được tải, vì vậy AngularJS được tải hai lần; và angular-route.js Tải tập tin trước tập tin mà nó phụ thuộc vào.

Code Giải thích

  1. Đầu tiên chúng tôi tạo ra một mô-đun Đối với ứng dụng AngularJS của chúng tôi, điều này là cần thiết để tạo một directive tùy chỉnh vì directive sẽ được tạo bằng cách sử dụng module này.
  2. Hiện tại chúng ta đang tạo một chỉ thị tùy chỉnh có tên là “ng”.Guruvà định nghĩa một hàm tạo (factory function) sẽ chứa mã tùy chỉnh cho chỉ thị của chúng ta.
  3. Chúng ta đang sử dụng tham số template, một tham số được AngularJS định nghĩa cho các directive tùy chỉnh. Trong đó, chúng ta định nghĩa rằng bất cứ khi nào directive này được sử dụng, thì chỉ cần sử dụng giá trị của template và chèn nó vào mã gọi.
  4. Giờ đây, chúng ta đang sử dụng chỉ thị “ng-guru” do chính chúng ta tạo ra. Khi làm như vậy, giá trị mà chúng ta đã định nghĩa cho mẫu của mình, <div>Angular JS Tutorial</div>, bây giờ sẽ được tiêm vào đây.

Đặt tên và chuẩn hóa chỉ thị

Sự không trùng khớp tên giữa JavaMã script và HTML thường gây khó hiểu cho người mới bắt đầu. AngularJS bình thường hóa mọi tên phần tử và thuộc tính trước khi khớp: nó loại bỏ bất kỳ x- or data- tiền tố, sau đó chuyển đổi tên được phân tách bởi -, : or _ viết theo kiểu camelCase. Đó là lý do tại sao ngGuru diêm ng-guru, và tại sao data-ng-guru Cũng được thôi. Dạng camelCase mới là tên gọi chính xác; kebab-case chỉ đơn giản là cách viết trong HTML.

⚠️ Điều chỉnh: Văn bản gốc nói rằng tên của chỉ thị tùy chỉnh “phải bắt đầu bằng các chữ cái 'ng'”. Tài liệu chính thức của AngularJS Ngược lại, lại khuyên: đừng bao giờ thêm tiền tố vào các chỉ thị của chính bạn bằng nghoặc chúng có thể xung đột với một hàm tích hợp sẵn trong tương lai. Hãy sử dụng tiền tố của riêng bạn, chẳng hạn như g99Guru Viết như g99-guru.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Tạo chỉ thị tùy chỉnh

Kết quả hiển thị cho thấy rõ ràng rằng chỉ thị ng-guru tùy chỉnh của chúng ta, có định nghĩa mẫu để hiển thị văn bản tùy chỉnh, được hiển thị trong trình duyệt. Bước tiếp theo là đặt một thứ gì đó có giá trị để tái sử dụng vào bên trong mẫu đó.

Cách tạo chỉ thị có thể tái sử dụng

Chúng ta đã thấy sức mạnh của chỉ thị tùy chỉnh nhưng chúng ta có thể nâng điều đó lên một tầm cao mới bằng cách xây dựng các chỉ thị có thể sử dụng lại của riêng mình.

Ví dụ, giả sử chúng ta muốn chèn mã để luôn hiển thị các thẻ HTML bên dưới trên nhiều màn hình, về cơ bản chỉ là ô nhập liệu cho "Tên" và "tuổi" của người dùng.

Tạo chỉ thị có thể sử dụng lại

Để tái sử dụng đoạn mã này trên nhiều màn hình mà không cần phải viết mã lại mỗi lần, chúng ta tạo một control chính, hay directive, trong AngularJS để chứa hai control này.

Vì vậy, thay vì lặp lại đoạn mã đó trên mọi màn hình, chúng ta nhúng nó vào một directive và gọi directive đó. Ảnh chụp màn hình bên dưới đánh dấu dòng duy nhất thay đổi.

Tạo chỉ thị có thể sử dụng lại

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('ngGuru',function(){
        return {

            template: '&nbsp;&nbsp;Name <input type="text"><br><br>&nbsp;&nbsp;&nbsp;Age<input type="text">'
        };
    });

</script>

</body>
</html>

Code Giải thích

  • Trong đoạn mã của chúng ta cho một chỉ thị tùy chỉnh, điều thay đổi chỉ là giá trị được truyền cho tham số mẫu. Thay vì một thẻ đơn giản hoặc một dòng văn bản, chúng ta đang nhập toàn bộ đoạn mã của hai điều khiển nhập liệu cho "Tên" và "Tuổi" cần hiển thị trên trang của chúng ta.

💡 Mẹo: Một mẫu dài như thế này nên được lưu trong một tệp riêng. Trao đổi template cho templateUrl: 'name-age.html'.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Tạo chỉ thị có thể sử dụng lại

Từ kết quả trên, ta có thể thấy đoạn mã từ mẫu của chỉ thị tùy chỉnh đã được thêm vào trang. Mẫu này vẫn đang ở dạng tĩnh, vì vậy bước tiếp theo là cung cấp dữ liệu cho nó.

Các chỉ thị và phạm vi trong AngularJS

phạm vi Nó được định nghĩa là chất kết dính liên kết bộ điều khiển với giao diện người dùng bằng cách quản lý dữ liệu giữa giao diện người dùng và bộ điều khiển.

Khi tạo các directive AngularJS tùy chỉnh, theo mặc định chúng sẽ có quyền truy cập vào đối tượng scope trong controller cha. Đó là cùng một đối tượng scope, không phải là bản sao.

Bằng cách này, lệnh tùy chỉnh sẽ dễ dàng sử dụng dữ liệu được chuyển đến bộ điều khiển chính.

Hãy xem một ví dụ về cách chúng ta có thể sử dụng phạm vi của bộ điều khiển cha trong chỉ thị tùy chỉnh của mình. Ảnh chụp màn hình bên dưới đánh số bốn bước.

Các chỉ thị và phạm vi trong AngularJS

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.controller('DemoController',function($scope) {
        $scope.tutorialName = "Angular JS";

    });

        app.directive('ngGuru',function(){
        return {
         template: '<div>{{tutorialName}}</div>'
     }
    });

</script>

</body>
</html>

Code Giải thích

  1. Đầu tiên, chúng ta tạo một bộ điều khiển có tên là “DemoController”. Trong bộ điều khiển này, chúng ta định nghĩa một biến có tên là tutorialName và gắn nó vào đối tượng scope trong một câu lệnh duy nhất: $scope.tutorialName = "Angular JS".
  2. Trong lệnh tùy chỉnh, chúng ta có thể gọi biến “guideName” bằng cách sử dụng một biểu thức. Biến này có thể truy cập được vì nó được xác định trong bộ điều khiển “DemoController”, bộ điều khiển này sẽ trở thành cha của lệnh này.
  3. Chúng tôi tham chiếu bộ điều khiển trong thẻ div, thẻ này sẽ hoạt động như thẻ div gốc của chúng tôi. Lưu ý rằng điều này cần được thực hiện trước tiên để lệnh tùy chỉnh của chúng tôi truy cập vào biến tutorialName.
  4. Cuối cùng, chúng tôi chỉ đính kèm chỉ thị tùy chỉnh “ng-guru” vào thẻ div của mình.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Các chỉ thị và phạm vi trong AngularJS

Kết quả đầu ra ở trên cho thấy rõ ràng rằng chỉ thị tùy chỉnh “ng-guru” của chúng ta sử dụng biến phạm vi tutorialName trong bộ điều khiển cha. Việc chia sẻ phạm vi của cha rất tiện lợi, nhưng không phải lúc nào cũng là điều bạn muốn.

Sử dụng bộ điều khiển với chỉ thị

AngularJS cung cấp khả năng truy cập trực tiếp vào biến thành viên của bộ điều khiển từ các lệnh tùy chỉnh mà không cần đến đối tượng phạm vi.

Điều này trở nên cần thiết trong một số trường hợp vì một ứng dụng có thể có nhiều đối tượng phạm vi thuộc về nhiều bộ điều khiển khác nhau, do đó có khả năng cao xảy ra trường hợp truy cập nhầm đối tượng phạm vi của bộ điều khiển không đúng.

Trong trường hợp như vậy, có một cách để nói rõ ràng "Tôi muốn truy cập bộ điều khiển này" từ chỉ thị của mình.

Chúng ta hãy cùng xem một ví dụ về cách chúng ta có thể đạt được điều này. Ảnh chụp màn hình đánh số bốn bước.

Sử dụng bộ điều khiển với chỉ thị

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <div ng-guru99=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.controller('DemoController',function() {
        this.tutorialName = "Angular";

    });

     app.directive('ngGuru99',function(){
        return {
         controller: 'DemoController',

          controllerAs: 'ctrl',

          template: '{{ctrl.tutorialName}}'
     };
    });

</script>

</body>
</html>

Code Giải thích

  1. Đầu tiên, chúng ta tạo một bộ điều khiển có tên là “DemoController”. Trong bộ điều khiển này, chúng ta sẽ định nghĩa một biến có tên là “tutorialName” và lần này, thay vì gắn nó vào đối tượng scope, chúng ta sẽ gắn trực tiếp nó vào bộ điều khiển.
  2. Trong chỉ thị tùy chỉnh của chúng tôi, chúng tôi đặc biệt đề cập đến việc chúng tôi muốn sử dụng bộ điều khiển “DemoController” bằng cách sử dụng từ khóa tham số bộ điều khiển.
  3. Chúng ta tạo tham chiếu đến bộ điều khiển bằng cách sử dụng tham số “controllerAs”. Tham số này được định nghĩa bởi AngularJS và là cách để tham chiếu đến bộ điều khiển bằng một bí danh.
  4. Cuối cùng, trong mẫu của chúng ta, chúng ta sử dụng tham chiếu được tạo ở bước 3 và sử dụng biến thành viên được gắn trực tiếp vào bộ điều khiển ở bước 1.

Lưu ý: Có thể truy cập nhiều bộ điều khiển trong một chỉ thị bằng cách chỉ định các khối tương ứng của bộ điều khiển, controllerAs và các câu lệnh mẫu. Để truy cập một cha mẹ Thay vào đó, hãy sử dụng bộ điều khiển của chỉ thị. require.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Sử dụng bộ điều khiển với chỉ thị

Kết quả đầu ra cho thấy rõ ràng rằng chỉ thị tùy chỉnh đang truy cập vào DemoController và biến thành viên tutorialName được gắn với nó, và hiển thị văn bản “Angular”. Cả hai cách tiếp cận đều vẫn đọc từ một phạm vi dùng chung, điều mà phạm vi cô lập ngăn chặn.

Sự khác biệt giữa các liên kết @, =, & và < trong phạm vi Isolate

Một chỉ thị có phạm vi chia sẻ với chỉ thị cha của nó chỉ có thể được sử dụng một lần cho mỗi bộ điều khiển, vì hai bản sao sẽ tranh giành cùng một biến. scope đối tượng tạo ra một phạm vi cô lậpChỉ thị này không nhìn thấy gì bên ngoài ngoại trừ các thuộc tính bạn liệt kê. Mỗi mục sử dụng một ký hiệu tiền tố để khai báo cách giá trị của nó được truyền đi.

Chiều hướng Giá trị nhận được Sử dụng nó cho
@ Lối vào một chiều Thuộc tính dưới dạng chuỗi nội suy Nhãn, tiêu đề, bất kỳ văn bản thuần túy nào
= Hai chiều Bản thân vật thể sống hoặc giá trị đó Mô hình mà chỉ thị ghi lại
& Lời kêu gọi ra ngoài Một hàm đánh giá một biểu thức trong phạm vi bên ngoài. Các hàm gọi lại như khi đóng hoặc khi lưu.
< Lối vào một chiều Giá trị được đánh giá, không bao giờ được viết tăng lên. Dữ liệu chỉ đọc, được thêm vào trong AngularJS 1.5.

💡 Mẹo: Với tới < trước =Liên kết một chiều giúp việc theo dõi dễ dàng hơn và ngăn chặn một thành phần âm thầm thay đổi dữ liệu của bên gọi nó. Phần tiếp theo sử dụng @.

Chỉ thị và thành phần AngularJS: ng-transclude

Như đã đề cập trước đó, AngularJS được thiết kế để mở rộng chức năng của... HTML. Và chúng ta đã thấy cách chúng ta có thể chèn mã bằng cách sử dụng các lệnh tùy chỉnh có thể sử dụng lại.

Nhưng trong phát triển ứng dụng web hiện đại, cũng có một khái niệm về phát triển...ping Web components, về cơ bản có nghĩa là tạo ra các thẻ HTML riêng của chúng ta có thể được sử dụng như các thành phần trong mã của chúng ta.

Do đó, AngularJS cung cấp một cấp độ sức mạnh khác để mở rộng các thẻ HTML bằng cách cho phép bao bọc bất kỳ mã đánh dấu nào mà người gọi đặt bên trong thẻ.

Việc này được thực hiện bởi “ng-transcludeChỉ thị này cho AngularJS biết cần phải nắm bắt mọi thứ được đặt bên trong thẻ tùy chỉnh trong mã HTML và đưa chúng vào mẫu tại vị trí đó.

Chúng ta hãy xem một ví dụ về cách chúng ta có thể đạt được điều này. Ảnh chụp màn hình được đánh số cho năm điểm sau đây.

Các chỉ thị và thành phần của AngularJS

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <pane title="{{title}}">Angular JS</pane>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('pane',function(){
        return {

            transclude:true,
            scope :{title:'@'},
            template: '<div style="border: 1px solid black;"> '+
                        '<ng-transclude></ng-transclude>'+
                            '</div>'
        };
    });

</script>

</body>
</html>

Code Giải thích

  1. Chúng tôi sử dụng chỉ thị này để định nghĩa một thẻ HTML tùy chỉnh có tên là “pane”, với một hàm tạo cung cấp mã cho thẻ đó. Trong kết quả đầu ra, thẻ pane hiển thị văn bản “Angular JS” trong một hình chữ nhật có viền đen liền mạch.
  2. Thuộc tính “transclude” phải được đặt thành true, điều này cho AngularJS biết cần giữ nguyên mã HTML bên trong và cung cấp nó cho các thành phần khác. ng-transclude.
  3. Trong đối tượng phạm vi, chúng ta đang khai báo một liên kết tiêu đề. Các thuộc tính thường được viết dưới dạng cặp tên/giá trị như sau: name="value"Trong trường hợp của chúng ta, thuộc tính trên thẻ pane là “title”, và ký hiệu “@” yêu cầu AngularJS sao chép thuộc tính đó dưới dạng chuỗi nội suy.
  4. Mẫu này vẽ đường viền đen đậm để chúng ta dễ điều khiển và đánh dấu vị trí chèn mã HTML.
  5. Cuối cùng, chúng ta gọi thẻ HTML tùy chỉnh của mình cùng với thuộc tính tiêu đề đã được định nghĩa.

⚠️ Điều chỉnh: Văn bản gốc mô tả "@" là "yêu cầu từ Angular". Đây không phải là hình thức: @ là một trong bốn ký hiệu ràng buộc phạm vi cô lập trong bảng trên và luôn trả về một chuỗi. Mẫu này cũng không bao giờ hiển thị {{title}}và không có bộ điều khiển nào định nghĩa titleDo đó, chỉ có văn bản được nhúng mới hiển thị.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Các chỉ thị và thành phần của AngularJS

  • Kết quả hiển thị phần tử khung tùy chỉnh được tạo thành một hộp có viền chứa văn bản được nhúng "Angular JS".

Một chỉ thị cũng có thể chứa các chỉ thị khác, đó là cách các thành phần lớn hơn được lắp ráp với nhau.

Chỉ thị lồng nhau

Các chỉ thị trong AngularJS có thể lồng nhau. Giống như các mô-đun bên trong hoặc các hàm trong bất kỳ hệ thống nào khác. ngôn ngữ lập trình, bạn có thể cần phải nhúng các chỉ thị vào nhau.

Bạn có thể hiểu rõ hơn về điều này bằng cách xem ví dụ dưới đây.

Trong ví dụ này, chúng ta đang tạo 2 chỉ thị gọi là “outer” và “inner”.

  • Lệnh bên trong hiển thị một văn bản có tên là “Inner”.
  • Trong khi lệnh bên ngoài thực sự thực hiện lệnh gọi đến lệnh bên trong để hiển thị văn bản có tên là “Inner”.

Ảnh chụp màn hình bên dưới đánh dấu cả hai định nghĩa chỉ thị và điểm mà chỉ thị này gọi chỉ thị kia.

Chỉ thị lồng nhau

</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <outer></outer>
</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('outer',function(){
        return {

            restrict:'E',
            template: '<div><h1>Outer</h1><inner></inner></div>',
        }});

    app.directive('inner',function(){
        return {

            restrict:'E',
            template: '<div><h1>Inner</h1></div>',
        }
    });
</script>

</body>
</html>

⚠️ Cảnh báo — lỗi này vẫn được giữ nguyên trong danh sách này: Danh sách đã công bố bắt đầu từ </head>, bỏ lỡ buổi khai mạc <!DOCTYPE html>, <html><head> các dòng. Hãy thêm chúng trước khi chạy.

Code Giải thích

  1. Chúng tôi đang tạo một lệnh có tên là "outer" sẽ hoạt động như lệnh gốc của chúng tôi. Lệnh này sau đó sẽ thực hiện lệnh gọi đến lệnh "bên trong".
  2. restrict:'E' Tùy chọn này cho AngularJS biết cần khớp với từng chỉ thị bằng cách nào. thành phần tên, đó là lý do tại sao chúng có thể được viết dưới dạng thẻ. <outer><inner>Chữ 'E' là viết tắt của từ 'Element' (nguyên tố).
  3. Ở đây chúng ta đang tạo chỉ thị bên trong hiển thị văn bản “Bên trong” trong thẻ div.
  4. Trong mẫu của chỉ thị bên ngoài, chúng ta đang gọi chỉ thị bên trong. Vì vậy, ở đây chúng ta đang chèn mẫu từ chỉ thị bên trong vào chỉ thị bên ngoài.
  5. Cuối cùng, chúng ta trực tiếp gọi ra chỉ thị bên ngoài.

⚠️ Điều chỉnh: Văn bản gốc tuyên bố rằng restrict:'E' Cần có lệnh này để “đảm bảo dữ liệu từ chỉ thị bên trong có sẵn cho chỉ thị bên ngoài”. Tuy nhiên, nó không làm điều đó; nó chỉ kiểm soát. làm thế nào Một chỉ thị có thể được viết. Lồng nhau hoạt động vì trình biên dịch tiếp tục duyệt qua mẫu mà nó vừa chèn vào. Để chia sẻ dữ liệu, hãy sử dụng requirecontroller.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Chỉ thị lồng nhau

Từ đầu ra,

  • Có thể thấy rằng cả chỉ thị bên ngoài và bên trong đều đã được gọi, và văn bản trong cả hai thẻ div đều được hiển thị.

Việc hiển thị mã HTML chỉ là một nửa chức năng của một directive; nửa còn lại là phản hồi lại người dùng.

Xử lý các sự kiện trong một chỉ thị

Sự kiện Các sự kiện như nhấp chuột hoặc nhấp nút có thể được xử lý từ bên trong chính các directive. Điều này được thực hiện bằng cách sử dụng hàm `link`. Hàm `link` cho phép directive tự gắn vào các phần tử DOM trong trang HTML.

Cú pháp:

Cú pháp của hàm liên kết được thể hiện như bên dưới.

link: function ($scope, element, attrs)

Hàm liên kết thường chấp nhận 3 tham số: phạm vi, phần tử mà chỉ thị được liên kết và các thuộc tính của phần tử đích. Hai tham số nữa, bộ điều khiển bắt buộc và hàm chuyển đổi, sẽ được thêm vào khi cần thiết.

Giai đoạn biên dịch so với giai đoạn liên kết

AngularJS xử lý một directive qua hai lượt, và việc biết được lượt nào dẫn đến lượt nào sẽ giúp bạn biết mã của mình nên đặt ở đâu.

  • Biên dịch Thao tác này chỉ được thực hiện một lần trên phần tử mẫu, trước khi bất kỳ phạm vi nào tồn tại. Nó phù hợp với các chỉnh sửa cấu trúc được chia sẻ bởi mọi bản sao.
  • liên kết Hàm này chỉ chạy một lần cho mỗi instance, sau khi template được sao chép và scope được gán. Các listener DOM và các thao tác đọc scope thuộc về phần này.

Vì hàm compile không có phạm vi, nên bất cứ thứ gì cần dữ liệu đều thuộc về hàm link, đó là lý do tại sao ví dụ bên dưới định nghĩa như vậy. link một mình.

Chúng ta hãy xem một ví dụ về cách chúng ta có thể thực hiện điều này. Ảnh chụp màn hình đánh số bốn điểm bên dưới.

Xử lý các sự kiện trong một lệnh

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru="">Click Me</div>
</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('ngGuru',function(){
        return {

            link:function($scope,element,attrs) {
                element.bind('click',function () {
                    element.html('You clicked me');
                });}
        }});
</script>

</body>
</html>

Code Giải thích

  1. Chúng tôi sử dụng hàm liên kết được định nghĩa trong AngularJS để cung cấp cho chỉ thị khả năng truy cập các sự kiện trong DOM HTML.
  2. Chúng ta sử dụng từ khóa 'element' vì muốn phản hồi sự kiện của một phần tử DOM HTML, trong trường hợp này là phần tử "div". Sau đó, chúng ta sử dụng hàm "bind" để thêm chức năng tùy chỉnh vào sự kiện click của phần tử. Từ khóa 'click' được sử dụng để chỉ sự kiện click của bất kỳ điều khiển HTML nào.
  3. Ở đây, chúng ta muốn thay thế nội dung HTML bên trong của một phần tử, trong trường hợp này là phần tử div, bằng dòng chữ 'You clicked me'.
  4. Ở đây chúng tôi đang xác định thẻ div để sử dụng lệnh tùy chỉnh ng-guru.

💡 Mẹo: Một chỉ thị nên tự dọn dẹp sau khi hoàn thành. Hãy loại bỏ bất kỳ trình lắng nghe nào tồn tại lâu hơn phần tử bên trong. element.on('$destroy', ...)hoặc trang đó bị rò rỉ bộ nhớ.

Nếu đoạn mã thực thi thành công, kết quả sẽ hiển thị như sau.

Đầu ra:

Xử lý các sự kiện trong một lệnh

  • Ban đầu, dòng chữ "Click Me" sẽ hiển thị cho người dùng, vì đó là nội dung được định nghĩa bên trong thẻ div. Khi bạn nhấp vào thẻ div, kết quả hiển thị bên dưới sẽ thay thế.

Xử lý các sự kiện trong một lệnh

Mỗi ví dụ trên đều sử dụng một hoặc hai thuộc tính của cùng một đối tượng định nghĩa. Toàn bộ tập hợp các thuộc tính này rất đáng để lưu giữ.ping đến tận tay.

Tham chiếu thuộc tính đối tượng định nghĩa chỉ thị

Đối tượng được trả về bởi một directive factory là Đối tượng định nghĩa chỉ thịMỗi thuộc tính trả lời một câu hỏi về cách thức hoạt động của chỉ thị.

Bất động sản Mặc định Những gì nó
hạn chế 'EA' Các dạng nào khớp nhau: E phần tử, A thuộc tính, C lớp, M chú thích
mẫu không ai Mã đánh dấu nội tuyến được chèn vào phần tử khớp.
templateUrl không ai Đường dẫn đến tệp mẫu, được tải về một lần rồi lưu vào bộ nhớ cache.
phạm vi sai false chia sẻ phạm vi của đối tượng cha, true tạo ra một đối tượng con, một đối tượng cô lập.
điều khiển không ai Hàm khởi tạo cung cấp API mà các chỉ thị khác có thể yêu cầu.
bộ điều khiển như không ai Bí danh cho bộ điều khiển bên trong mẫu
yêu cầu không ai Bộ điều khiển của một chỉ thị khác cần chèn; ^ tìm kiếm các phần tử cha, ^^ bỏ qua chính nó, ? tùy chọn
liên kết này không ai Chức năng trên mỗi thể hiện: phạm vi, phần tử, thuộc tính, bộ điều khiển, hàm chuyển đổi
biên dịch không ai Chạy một lần trên mẫu trước khi bất kỳ phạm vi nào tồn tại.
bao gồm sai Giữ nguyên cấu trúc đánh dấu bên trong ban đầu cho ng-transclude.
ưu tiên 0 Thứ tự biên dịch trên một phần tử chung; phần tử có giá trị cao hơn sẽ được thực thi trước.
thiết bị đầu cuối sai Dừng các chỉ thị có mức độ ưu tiên thấp hơn đối với phần tử đó.
thay thế sai Thay thế phần tử bằng mẫu. Đã bị loại bỏ kể từ phiên bản 1.3.

💡 Mẹo: Bắt đầu với restrict, templatelink, thêm vào scope để tái sử dụng, controllerrequire đối với các cuộc gọi trực tiếp giữa các cấp quản lý, và rời đi priorityterminal một mình.

Câu Hỏi Thường Gặp

Thành phần (component), được thêm vào trong AngularJS 1.5, là một chỉ thị (directive) với các thiết lập mặc định: chỉ khớp với phần tử, phạm vi cô lập (isolate scope) và bộ điều khiển (controller). Sử dụng thành phần cho một giao diện độc lập và sử dụng chỉ thị khi bạn cần truy cập DOM ở cấp độ liên kết.

Thông thường tên không được chuẩn hóa chính xác, hoặc lệnh restrict loại trừ dạng bạn đã sử dụng. Một chỉ thị được đăng ký là của tôiBox khớp với my-box, không phải mybox, và thẻ phần tử cần có thuộc tính restrict để bao gồm E.

Vâng. AI Các trợ lý ánh xạ phạm vi cô lập lên các trình trang trí Đầu vào và Đầu ra, và một mẫu lên mẫu thành phần. RevHãy xem xét mã DOM của các hàm chuyển đổi và liên kết bằng tay, vì chúng hiếm khi được dịch một cách trơn tru.

Trợ lý AI tạo ra kiểm tra đơn vị Các khung sườn này biên dịch chỉ thị, gắn phạm vi và kiểm tra kết quả đầu ra. Chúng rất tốt trong việc liệt kê các trường hợp ngoại lệ, vì vậy hãy coi các câu lệnh kiểm tra được tạo ra như một bản nháp ban đầu.

Hãy sử dụng templateUrl khi mã HTML dài hơn một hoặc hai dòng. Tệp này có thể chỉnh sửa bằng các công cụ HTML thông thường và chỉ được tải về một lần, sau đó được sử dụng từ bộ nhớ đệm mẫu cho mọi lần sử dụng sau đó.

Tóm tắt bài viết này với: