Angular 属性表达式未在内部指令中求值

Angular attribute expression not evaluating inside directive

为什么 link 使用 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

从指令访问控制器作用域的一种方法是使

scope: false

详细了解指令 here

HTH

所以我相信您混淆了您在这里处理的两个范围。通过使用像你在这里这样的隔离范围,你正在复制 text 属性的 插值 (在遇到指令时针对范围进行评估(控制器范围在您的示例中))到名为 '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

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

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

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

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