有没有办法在编译阶段访问指令中的对象。因为编译阶段不提供范围。和attrs.data将返回一个字符串,这是获取数据的最佳方式。
**
<body ng-controller="MainCtrl">
<h2>MainCtrl</h2>
{{data}}
<div dir data="data.items">
</div>
</body>
**
angular.module('app', [])
.controller('MainCtrl', function($scope) {
$scope.data = {
items: [{
id: 1,
name: "first"
}, {
id: 2,
name: "second"
}, {
id: 3,
name: "third"
}]
}
})
.directive('dir', function() {
return {
replace: true,
restrict: 'A',
compile: function(element, attrs) {
//need to access $scope.data defined in MainCtrl.
});
}
}
})
答案 0 :(得分:0)
隔离范围是绑定父范围
数据的好模式<div dir data="data.items">
并将其提供给指令的link
或controller
,就像那样
angular.module('app').directive('dir', function() {
return {
scope: {
data: '='
},
...
}
})
或者您可以使用单向绑定
<div dir data="{{data.items}}">
在link
函数attrs.data
中获取它。这就是Angular期望它完成的方式。
您的问题本身描述了编译阶段发生的事情。您无法访问范围,
<div dir data="{{data.items}}">
也无济于事,因为attrs
中的属性未在compile
函数中进行插值。这就是为什么它不能那样工作的原因:MainCtrl
在指令的compile
之后运行。
答案 1 :(得分:0)
渲染过程分为编译和链接阶段是角度框架的基石。这种结构意味着您可以在模板实例化之前有机会摆弄模板&#39;在链接阶段使用范围数据。
指令的编译回调只运行一次 - 而链接回调可能会以不同的范围运行任意次。
那么,如果要传递给angular的模板取决于应用程序中的某些数据,该怎么办?一旦你的指令注册了angular,它的模板就是不可变的。
我们无法使用范围 - 所以我所做的就是拥有一个javascript对象 - 让它称之为注册表 - 它位于角度上下文之外。然后,我将需要访问的数据从编译阶段放入注册表,并通过模板中的属性将密钥传递到编译阶段,您可以在编译阶段访问该模板。
使用此方法时,需要注意不要泄漏内存。可能通过使用$ destroy回调清除相应的注册表项。
答案 2 :(得分:-1)
让我们可以访问compile
scope
angular.module('app', [])
.controller('app', function($scope) {
this.data = {
items: [{
id: 1,
name: "first"
}, {
id: 2,
name: "second"
}, {
id: 3,
name: "third"
}]
}
})
.directive('dir', function() {
return {
replace: true,
restrict: 'A',
scope: {
data: '='
},
compile: function(element) {
setTimeout(function() {
alert(JSON.stringify(element.scope().ctrl.data))
}, 1)
}
}
})
angular.bootstrap(document.body, ['app'])