有一个更好的办法。您当前的解决方案是设置三个手表 - 两个是使用“=”绑定创建的,然后是您创建的额外 $watch 来制作副本。 $手表相对较贵。
这是不创建任何手表的替代方案:
.directive('myCustomDirective', [
'$log', function ($log) {
return {
restrict: 'E',
templateUrl: '<div ng-click="clicked()">Click me for current value</div>',
scope: {
item: '&'
},
controller: function($scope) {
$scope.clicked = function(){
alert(item()); //item() returns current value of parent's $scope.item property
}
$scope.val = item(); //val is the initial value of $parent.item
$scope.val = 42; //$parent.item is unaffected.
}
}])
& 被严重误解。虽然它可用于将函数传递到隔离的作用域中,但它实际上的作用是:
提供了一种在父级上下文中执行表达式的方法
范围
它在指令中生成一个函数,调用该函数时,会在父作用域的上下文中执行表达式。该表达式不必是函数或函数调用。它可以是任何有效的角度表达式。
所以在你的例子中:
<my-custom-directive data-item="item"></my-custom-directive>
scope: {
item: '&'
}
指令中的 $scope.item 将是您可以在控制器或模板中调用的函数。调用该函数将返回父作用域中“item”引用的对象。没有与 & 的绑定 - 不使用手表。
“单向绑定”用词不当的地方是,使用 & 时,该指令无法更改 $parent.item 的值,而使用“=”时,该指令凭借创建的 $watches 可以更改。它也不是“一次性”,因为它在技术上根本不受限制。
由于 Angular 用于生成函数的机制涉及 $parse,因此指令可以传入“局部变量”,用指令中的值覆盖表达式中的值。因此,在指令控制器中,如果您这样做:
item({item: 42})
无论父作用域中 item 的值如何,它总是返回 42。正是此功能使得 & 对于使用指令中的数据在父作用域上执行函数表达式非常有用。