Hiểu tùy chọn transclude của định nghĩa chỉ thị?


195

Tôi nghĩ rằng đây là một trong những khái niệm khó hiểu nhất đối với tôi bằng chỉ thị của angularjs.

Tài liệu từ http://docs.angularjs.org/guide/directive nói:

transclude - biên dịch nội dung của phần tử và làm cho nó có sẵn cho lệnh. Thường được sử dụng với ngTransclude. Ưu điểm của loại trừ là chức năng liên kết nhận được chức năng loại trừ được liên kết trước với phạm vi chính xác. Trong một thiết lập điển hình, widget tạo ra một phạm vi cô lập, nhưng loại trừ không phải là một đứa trẻ, mà là anh chị em của phạm vi cô lập. Điều này làm cho tiện ích có thể có trạng thái riêng tư và loại trừ được ràng buộc với phạm vi cha mẹ (cách ly trước).

  • đúng - bao gồm nội dung của chỉ thị.
  • 'Phần tử' - bao gồm toàn bộ phần tử bao gồm mọi chỉ thị được xác định ở mức ưu tiên thấp hơn.

Nó nói transcludethường được sử dụng với ngTransclude. Nhưng mẫu từ tài liệu của ngTransclude hoàn toàn không sử dụng ngTranscludechỉ thị.

Tôi muốn một số ví dụ tốt để giúp tôi hiểu điều này. Tại sao chúng ta cần nó? Nó giải quyết cái gì? Làm thế nào để sử dụng nó?


FYI ... liên kết đang hoạt động ít nhất bây giờ
Sandy

Câu trả lời:


518

Hãy xem xét một lệnh được gọi là myDirective trong một phần tử và phần tử đó có kèm theo một số nội dung khác, giả sử:

<div my-directive>
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Nếu myDirective đang sử dụng một mẫu, bạn sẽ thấy rằng nội dung của <div my-directive>nó sẽ được thay thế bằng mẫu chỉ thị của bạn. Vì vậy, có:

app.directive('myDirective', function(){
    return{
        template: '<div class="something"> This is my directive content</div>'
    }
});

sẽ dẫn đến kết xuất này:

<div class="something"> This is my directive content</div> 

Lưu ý rằng nội dung của phần tử gốc của bạn <div my-directive> sẽ bị mất (hoặc nói tốt hơn, được thay thế). Vì vậy, hãy nói lời tạm biệt với những người bạn này:

<button>some button</button>
<a href="#">and a link</a>

Vậy, nếu bạn muốn giữ <button>...<a href>...trong DOM thì sao? Bạn sẽ cần một cái gì đó gọi là loại trừ. Khái niệm này khá đơn giản: Bao gồm nội dung từ nơi này sang nơi khác . Vì vậy, bây giờ chỉ thị của bạn sẽ trông giống như thế này:

app.directive('myDirective', function(){
    return{
        transclude: true,
        template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>'
    }
});

Điều này sẽ khiến:

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>. 

Tóm lại, về cơ bản, bạn sử dụng transclude khi bạn muốn bảo toàn nội dung của một phần tử khi bạn đang sử dụng một lệnh.

Ví dụ mã của tôi là ở đây . Bạn cũng có thể hưởng lợi từ việc xem này .


12
Có vẻ như họ đã thay đổi chức năng một chút. Ít nhất là trong phiên bản> = 1.2.9. Nội dung từ mẫu không được thêm vào nội dung được hiển thị. Xem câu trả lời của @ TechExplorer bên dưới
Tarjei Romtveit

20
Một câu trả lời rất, rất tốt. Cách trên bình thường. Bạn có ví dụ hay và "đây là nội dung chỉ thị của tôi" giúp bạn đọc rất dễ dàng trong phiên bản kết xuất. Tôi không hiểu tại sao Angular phải sử dụng các thuật ngữ và khái niệm phức tạp và sau đó không bao gồm các ví dụ dễ hiểu như của bạn. +2
miễn phí

Có ai biết nếu nội dung được nhúng có thể tham chiếu đến các trường phạm vi cô lập của lệnh không? Nó nói ở trên rằng việc loại trừ là anh chị em, không phải là trẻ em, trong phạm vi cô lập ... vì vậy tôi cho rằng điều đó không thể - nhưng tự hỏi liệu ai đó có thể xác nhận hoặc cho tôi biết nếu có thể
Simon Green

@UladzimirHavenchyk cảm ơn, họ đã chuyển video sang nơi khác. Tôi đã sửa liên kết cho phù hợp.
odiseo

4
@odiseo, bạn có thể vui lòng viết TẤT CẢ các tài liệu Angular đơn giản, dễ hiểu tiếng Anh như thế này không! + nhiều 1.
Dan Hodson

76

Tôi nghĩ điều quan trọng là phải đề cập đến những thay đổi trong hành vi trên trong phiên bản mới của AngularJS. Tôi đã dành một giờ cố gắng để đạt được kết quả trên với Angular 1.2.10.

Nội dung của phần tử với ng-transclude không được thêm vào mà được thay thế hoàn toàn.

Vì vậy, trong ví dụ trên, những gì bạn sẽ đạt được với 'transclude' sẽ là:

<div class="something">
    <button>some button</button>
    <a href="#">and a link</a>
</div>

và không

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Cảm ơn.


Để biết thêm thông tin về hành vi đã thay đổi trong Angular 1.2, hãy xem thay đổi eed299a .
Mark Rajcok

37

Những gì TechExplorer nói là đúng nhưng bạn có thể có cả hai nội dung bằng cách đưa vào mẫu của bạn một thẻ chứa đơn giản (như div hoặc span) với thuộc tính ng-transclude. Điều này có nghĩa là đoạn mã sau trong mẫu của bạn phải bao gồm tất cả nội dung

<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>

5
Đó là thông tin chính bị thiếu trong các câu trả lời khác
Matheus

4
Câu trả lời này thêm rất nhiều thông tin. ng-transcludelà thuộc tính đóng vai trò là người giữ chỗ, bên trong đó nội dung được nhúng sẽ được đặt.
BeingSuman

5

Từ Wiki:

"Trong khoa học máy tính, loại trừ là bao gồm một phần hoặc toàn bộ tài liệu điện tử vào một hoặc nhiều tài liệu khác bằng cách tham chiếu."

Tôi muốn thêm một cách sử dụng khác để loại trừ và đó là nó thay đổi thứ tự thực hiện của các hàm biên dịch và liên kết của các lệnh cha và con. Điều này có thể hữu ích khi bạn muốn biên dịch DOM con trước DOM gốc vì DOM gốc có thể phụ thuộc vào DOM con. Bài viết này đi sâu hơn và làm rõ nó rất tốt!

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-fifts-inside-angularjs-directives-part-2-transinating/


5

Các AngularJS Cập nhật 1.6.6 tài liệu bây giờ có một lời giải thích tốt hơn.

Transclude được sử dụng để tạo ra một Chỉ thị kết hợp các yếu tố khác

Đôi khi, mong muốn có thể vượt qua trong toàn bộ khuôn mẫu thay vì chuỗi hoặc đối tượng. Hãy nói rằng chúng tôi muốn tạo một thành phần "hộp thoại". Hộp thoại sẽ có thể bao bọc bất kỳ nội dung tùy ý.

Để làm điều này, chúng ta cần sử dụng tùy chọn transclude . Tham khảo ví dụ dưới đây.


script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

hộp thoại của tôi.html

<div class="alert" ng-transclude></div>

Kết quả biên dịch

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude làm cho nội dung của một lệnh với tùy chọn này có quyền truy cập vào phạm vi bên ngoài chỉ thị chứ không phải bên trong.

Điều này được minh họa trong ví dụ trước. Lưu ý rằng chúng tôi đã thêm một hàm liên kết trong script.js xác định lại tên là Jeff. Thông thường, chúng tôi hy vọng rằng {{name}} sẽ là Jeff. Tuy nhiên, trong ví dụ này, chúng ta thấy ràng buộc {{name}} vẫn là Tobias.

Thực hành tốt nhất : chỉ sử dụng transclude: truekhi bạn muốn tạo một lệnh bao bọc nội dung tùy ý.


0

transclude: true có nghĩa là thêm tất cả các phần tử được xác định trong lệnh của bạn với phần tử mẫu của lệnh của bạn.

if transclude: false, các phần tử này không được bao gồm trong html cuối cùng của chỉ thị mẫu chỉ thị được hiển thị.

transclude: phần tử có nghĩa là mẫu chỉ thị của bạn không được sử dụng chỉ phần tử được xác định trong lệnh của bạn được hiển thị dưới dạng html.

Khi bạn xác định lệnh của mình thì nó sẽ được giới hạn ở E và khi bạn thêm nó vào trang thì

<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.