角度范围绑定和(&符号)是一次性绑定吗?

Mat*_*att 4 javascript angularjs angularjs-scope angular-directive

角度范围绑定和(&符号)是一次性绑定吗?我认为它被称为单向绑定,但它是否也是一次性的?

比方说我有:

<my-custom-directive data-item="item" />
Run Code Online (Sandbox Code Playgroud)

我的指令声明如下:

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

我之所以询问绑定是否是一次性的原因是因为这似乎是我所观察到的,即.如果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) {
   //....
   }
}])
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*ger 10

有一个更好的办法.您当前的解决方案是设置三个手表 - 两个是使用"="绑定创建的,然后是您创建的额外$ 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. 
    }

}])
Run Code Online (Sandbox Code Playgroud)

并且被高度误解.虽然它可以用于将函数传递到隔离的范围,但它实际上做的是:

提供了一种在父作用域的上下文中执行表达式的方法

它在指令中生成一个函数,在调用时,它在父作用域的上下文中执行表达式.表达式不必是函数或函数调用.它可以是任何有效的角度表达式.

所以在你的例子中:

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

scope: {
    item: '&'
}
Run Code Online (Sandbox Code Playgroud)

指令中的$ scope.item将是一个可以在控制器或模板中调用的函数.调用该函数将返回父作用域中"item"引用的对象.没有与&绑定 - 没有使用手表.

"单向绑定"用词不当的地方是使用&,指令不能改变$ parent.item的值,在使用"="时,该指令凭借创建的$ watch可以.它也不是"一次性",因为它在技术上根本没有约束力.

由于angular用于生成函数的机制涉及$ parse,因此指令可以传入"locals",该函数使用指令中的值覆盖表达式中的值.因此,在指令控制器中,如果你这样做:

item({item: 42})
Run Code Online (Sandbox Code Playgroud)

无论父范围中的项的值如何,它总是返回42.正是这个特性使得使用指令中的数据在父作用域上执行函数表达式是有用的.