为什么链接使用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
答案 0 :(得分:2)
我推荐GregL的答案,但为了完整性:
就其本质而言,template
代码必须在 angular编译代码之前运行(显然,因为模板告诉angular它应该编译什么)。这就是为什么结果与您在link
函数中看到的结果不同,后者在编译之后发生。
如果您绝对必须执行手动插值,则可以使用$interpolate
服务角度提供。
答案 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';
});
答案 2 :(得分:0)