Angular属性表达式不评估内部指令

时间:2015-01-05 02:18:38

标签: angularjs angularjs-directive

为什么链接使用link属性评估指令内的表达式,但模板不是?请注意,我这里仅使用'link'来表示console.log。

我的最终目标是通过数据将数据传递到指令中,并将数据呈现为模板。

的index.html

<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@*" data-semver="1.3.7" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="app.js"></script>
</head>

<body ng-app="myApp">
  <div ng-controller="myCtrl">
      <my-directive text="{{data}}" />
  </div>
</body>

</html>

app.js

angular.module("myApp", []).directive("myDirective", function () {
  return {
      restrict: "E",
      scope: {
          text: "@text",
      },
      link: function(scope, element, attrs){
        console.log(attrs.text);
      },
      template: function(element, attrs){
        console.log(attrs.text);
      }
  };
}).controller('myCtrl',function($scope){
$scope.data = 'test';
});

输出:

{{data}}
test

3 个答案:

答案 0 :(得分:2)

我推荐GregL的答案,但为了完整性:

就其本质而言,template代码必须在 angular编译代码之前运行(显然,因为模板告诉angular它应该编译什么)。这就是为什么结果与您在link函数中看到的结果不同,后者在编译之后发生

如果您绝对必须执行手动插值,则可以使用$interpolate服务角度提供。

https://docs.angularjs.org/api/ng/service/ $插值

答案 1 :(得分:1)

所以我相信你混淆了你在这里处理的两个范围。通过使用此处的隔离范围,您将复制text属性的插值(在遇到指令时针对范围进行评估(示例中的控制器范围) ))隔离范围上称为“文本”的属性。因此,在您的指令模板中,您应该引用text来访问该值(在您的情况下为“test”)。

但是,根据您的评论,您确实希望能够传递要显示的指令的标记,就好像它是针对控制器的作用域运行一样。这就是 transclusion 的用途 - 被转换的内容将被放置在您在指令模板中指示的位置,并根据控制器的范围进行评估,因此{{data}}将正确解析为test

在这种情况下,您的标记将变为:

<my-directive>{{data}}</my-directive>

你的JS变成了:

angular.module("myApp", []).directive("myDirective", function() {
  return {
    restrict: "E",
    scope: {
      // no need for scope bindings here
    },
    transclude: true,
    link: function(scope, element, attrs) {
      // nothing to do here for now
    },
    template: '<div ng-transclude></div>',
  };
}).controller('myCtrl', function($scope) {
  $scope.data = 'test';
});

Working Plunker

答案 2 :(得分:0)

从指令访问控制器范围的一种方法是

scope: false

详细了解指令here

HTH