【问题标题】:Is the angular scope binding &(ampersand) a one time binding?角度范围绑定 &(&(&) 是一次性绑定吗?
【发布时间】:2015-06-15 07:35:51
【问题描述】:

角度范围绑定 &(&(&) 是一次性绑定吗? 我看到它被称为单向绑定,但它也是一次性的吗?

假设我有:

<my-custom-directive data-item="item" />

我的指令声明如下:

.directive('myCustomDirective', [
'$log', function ($log) {
return {
    restrict: 'E',
    templateUrl: '/template.html',
    scope: {
        dataItem: '&'
    }
    controller: function ($scope) {
        // ....
    }
}])

我之所以问绑定是否是一次性的,是因为这似乎是我所观察到的,就是这样。如果父作用域中的item 更新,则指令中的item 不会更新。

我说绑定是一次性的对吗?

为了实现我想要的,指令保留一个副本而不影响父范围的项目——我这样做了:

.directive('myCustomDirective', [
'$log', function ($log) {
return {
    restrict: 'E',
    templateUrl: '/template.html',
    scope: {
        dataItemOriginal: '='
    },
    link: function ($scope) {
        $scope.$watch('dataItemOriginal', function () {
            $scope.dataItem = window.angular.copy($scope.dataItemOriginal);
        });
    },
    controller: function ($scope) {
   //....
   }
}])

这是正确的还是有更好的方法?

【问题讨论】:

  • 什么是您需要不断更新的副本而不是在需要时复制它的用例?
  • 用例是我不知道该怎么做:-)
  • 一个简单的函数会不会说ng-click 不能满足您的需求?那么函数里面的$scope.dataItem = window.angular.copy($scope.dataItemOriginal);呢?如果您只需要快照副本,使用 $.watch 会很昂贵
  • &amp; 前缀用于将函数传递到隔离范围。是你想要的吗?此外,在前导 data 之后使用大写字符命名范围属性也是一个坏主意。这个属性data-item 将被解析为item,而不是dataItem

标签: javascript angularjs angularjs-scope angular-directive


【解决方案1】:

有更好的方法。您当前的解决方案是设置三个手表 - 两个是通过使用“=”绑定创建的,然后是您创建的额外 $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,因此指令可以传入“locals”,用指令中的值覆盖表达式中的值。所以,在指令控制器中,如果你这样做了:

item({item: 42})

它总是返回 42,不管父作用域中 item 的值。正是这个特性使得在父作用域上使用指令中的数据执行函数表达式非常有用。

【讨论】:

  • 这很好解释,唯一的例外是你没有解决 Yuriy Rozhovetskiy 在评论中提出的问题,即属性 data-item 中的前导 data- 将是剥离。所以你应该指的是item而不是dataItem
  • 我认为说它评估一个表达式而不是执行它会更准确。原因是,如果您有一个绑定的函数,它不会执行该函数,它只是评估表达式以提供正确范围的实际函数。然后如果你想执行那个函数,你可以。
猜你喜欢
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 2014-07-13
  • 1970-01-01
相关资源
最近更新 更多