25

是否可以以某种方式ngTransclude用于属性值,而不是替换内部 HTML 内容?例如这个简单的指令

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

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

并将其用作

<tag>foo</tag>

我想把它翻译成

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

有什么方法可以做到这一点,还是我必须使用属性而不是嵌入?

这是一个例子

4

4 回答 4

24

像这样的东西:

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

小提琴

于 2012-07-28T20:40:47.893 回答
7

另一种解决方案:

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

于 2012-12-02T11:41:41.403 回答
4

我最初知道您的问题是关于嵌入的,但是使用属性可以更简洁地解决这个问题。

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

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

和你的 html

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

译文:

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

此外,在最新版本的 Angular 中,有一个称为“一次性绑定”的功能,非常适合这种情况,您只希望/需要在初始化时一次性完成插值。语法如下所示:

{{::url}}

只需将模板中 {{url}} 的所有实例替换为上述内容即可。

于 2014-09-25T11:23:39.000 回答
2

Vadim 的答案可以通过使用该compile函数轻松修复,并返回将发生转换的 postLink 函数。

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

请参考https://docs.angularjs.org/api/ng/service/ $compile

$transclude函数曾经在函数中传递compile,但已被弃用,现在在link函数中。

于 2014-05-21T06:59:37.657 回答