How can I transclude into an attribute?

前端 未结 4 1664
独厮守ぢ
独厮守ぢ 2020-12-14 02:06

Is is possible to somehow use ngTransclude for an attribute value, instead of replacing inner HTML content? For example this simple directive

va         


        
相关标签:
4条回答
  • 2020-12-14 02:38

    Something like this:

    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.

    0 讨论(0)
  • 2020-12-14 02:44

    I know originally your question was about transclusion, but this problem is MUCH more succinctly solved using an attribute.

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

    and your html

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

    The translation:

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

    Also, with the very latest version of Angular, there is a feature called "one-time binding" that is perfect for situations just like this where you only want/need to fulfill the interpolated value one time, upon initialization. The syntax looks like this:

    {{::url}}
    

    Just replace all instances of {{url}} in your template with the above.

    0 讨论(0)
  • 2020-12-14 02:45

    Vadim's answer can be easily fixed by using the compile function, and returning the postLink function, where tranclusion will happen.

    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);
              });
            };
        }
      };
    });
    

    Please refer to https://docs.angularjs.org/api/ng/service/$compile

    The $transclude function used to be passed in the compile function, but it was deprecated, and is now in the link function.

    0 讨论(0)
  • 2020-12-14 02:47

    One more solution:

    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

    0 讨论(0)
提交回复
热议问题