2012-07-28 25 views
25

Có thể bằng cách nào đó sử dụng ngTransclude cho một giá trị thuộc tính, thay vì thay thế nội dung HTML bên trong? Ví dụ chỉ thị đơn giản nàyTôi có thể chuyển đổi thành một thuộc tính như thế nào?

var testapp = angular.module('testapp', []) 

testapp.directive('tag', function() { 
    return { 
    template: '<h1><a href="{{transcludeHere}}" ng-transclude></a></h1>', 
    restrict: 'E', 
    transclude: true 
    } 
}); 

và sử dụng nó như

<tag>foo</tag> 

Tôi muốn nó để dịch sang

<h1><a href="foo">foo</a></h1> 

Có cách nào để làm điều đó, hay tôi phải sử dụng một thuộc tính thay vì transcluding?

Dưới đây là một fiddle với ví dụ

Trả lời

24

Something như thế này:

var testapp = angular.module('testapp', []) 

testapp.directive('tag', function() { 
    return { 
    restrict: 'E', 
    template: '<h1><a href="{{transcluded_content}}">{{transcluded_content}}</a></h1>', 
    replace: true, 
    transclude: true, 
    compile: function compile(tElement, tAttrs, transclude) { 
     return { 
      pre: function(scope) { 
       transclude(scope, function(clone) { 
        scope.transcluded_content = clone[0].textContent; 
       }); 
      } 
     } 
    } 
    } 
});​ 

fiddle.

7

hơn Một giải pháp:

app.directive('tag', function($compile) { 
    return { 
    restrict: 'E', 
    template:"<h1></h1>", 
    transclude: 'element', 
    replace: true, 
    controller: function($scope, $element, $transclude) { 
     $transclude(function(clone) { 
     var a = angular.element('<a>'); 
     a.attr('href', clone.text()); 
     a.text(clone.text());   
     // If you wish to use ng directives in your <a> 
     // it should be compiled 
     //a.attr('ng-click', "click()"); 
     //$compile(a)($scope);  
     $element.append(a); 
     }); 
    } 
    }; 
}); 

Plunker: http://plnkr.co/edit/0ZfeLz?p=preview

+2

Đây sẽ là một câu trả lời tốt hơn nếu nó không có thao tác DOM bên trong bộ điều khiển – georgiosd

+0

Vâng, sử dụng '$ element' thường là một ý tưởng tồi. – mgol

+2

@georgiosd -> Thao tác DOM chính xác là những gì mà lệnh ngTransclude thực hiện. –

2

câu trả lời Vadim có thể được dễ dàng cố định bằng công compile chức năng, và trả lại chức năng postLink, nơi tranclusion sẽ xảy ra.

app.directive('tag', function ($compile) { 
    return { 
    restrict: 'E', 
    template: '<h1></h1>', 
    transclude: 'element', 
    replace: true, 
    compile: function($element, $attrs) { 
     return function ($scope, $element, $attrs, $controller, $transclude) { 
      $transclude(function(clone) { 
      var a = angular.element('<a></a>'); 
      a.attr('href', clone.text()); 
      a.text(clone.text());   
      // If you wish to use ng directives in your <a> 
      // it should be compiled 
      // a.attr('ng-click', 'click()'); 
      // $compile(a)($scope); 
      $element.append(a); 
      }); 
     }; 
    } 
    }; 
}); 

Vui lòng tham khảo https://docs.angularjs.org/api/ng/service/ $ biên dịch

Các $transclude chức năng sử dụng được thông qua trong compile chức năng, nhưng nó đã bị phản đối, và bây giờ là trong link chức năng.

4

Tôi biết ban đầu câu hỏi của bạn là về việc chuyển đổi, nhưng vấn đề này là MUCH được giải quyết gọn gàng hơn bằng cách sử dụng một thuộc tính.

var testapp = angular.module('testapp', []) 

testapp.directive('tag', function() { 
    return { 
    template: '<h1><a href="{{url}}">{{url}}</a></h1>', 
    restrict: 'E', 
    scope: { 
     url: '@' 
    } 
    } 
}); 

và html của bạn

<tag url="foo"></tag> 

Bản dịch:

<h1><a href="foo">foo</a></h1> 

Ngoài ra, với phiên bản mới nhất của góc, có một tính năng gọi là "một thời gian ràng buộc" đó là hoàn hảo cho các tình huống giống như thế này, nơi bạn chỉ muốn/cần hoàn thành giá trị nội suy một lần, khi khởi tạo. Cú pháp trông giống như sau:

{{::url}} 

Chỉ cần thay thế tất cả các trường hợp {{url}} trong mẫu của bạn ở trên.

Các vấn đề liên quan