javascript - 带有隔离范围的 Angular 双向绑定(bind)似乎是单向的

标签 javascript angularjs

我使用隔离范围编写了一个简单的点击编辑指令,以便它可以重用。当我使用它时, Controller 范围中的源值( '=' )永远不会更新,尽管其原始值应用于指令内。就好像绑定(bind)是单向的('@')。

代码如下:

app.directive("ngClickToEdit", function() {
    return {
        template:
            '<div>' +
                '<div ng-show="enabled">' +
                    '<input ng-change="validator()" ng-blur="enabled=false"  ng-model="source"/>' +
                '</div>' +
                    '<div ng-show="!enabled" ng-bind="source" ng-click="enable()"></div>' +
            '</div>',
        restrict: "E",
        replace: true,
        scope: {
            validator: '&',
            source: '=',
        },
        link: function(scope, element) {
            scope.enabled = false;

            var input = element.children()[0].firstChild;

            scope.enable = function() {
                scope.enabled = true;
                setTimeout(function() {
                    input.focus();
                    input.select();
                }, 200);
            };
        },
    };
});

这是 Controller 中的调用(编辑为包装在 ng-if div block 中):

<div ng-if='name'>
    <ng-click-to-edit validator='validateName()' source='name' />
</div>

当调用 Controller 范围中的 validateName() 时,“name”的值是原始值,而不是指令输入控件中的(更改的)值。模型未更新。为什么?

已解决: ng-if block 创建一个子作用域,将 name 作为字符串原语传递,因为 prototypal inheritance 。将对象引用传递到指令中可以解决该问题。查看revised plunker在这里。

最佳答案

这是因为外部作用域的名称尚未分配给内部作用域的。当您使用 "=" 声明隔离范围时,Angular $watch 会在两个值中进行更改(请参阅 code )并执行双向绑定(bind),但是调用 validator 时 $watches 尚未触发。

您可以使用以下代码进行检查:

$scope.validateName = function(){
  console.log("outside directive: name = " + $scope.name);

  $timeout(function(){
    console.log("but just after digest cycle: name = " + $scope.name);
  });
};

您可以做一些事情:

1) 您可以在 $timeout 之后触发验证器:

scope.localValidate = function(){
   $timeout(function(){ scope.validator(); });
};

和模板:

<input ng-change="localValidate()"..>

2) 您可以 $watch 来监视 source 中的更改,然后触发 $validator (而不是在 ng-change 中):

scope.$watch("source", function(){
    scope.validator();
});

3) 您可以将要验证的值传递到验证器函数中:

<input ng-change="validator({name: source})"..>

关于javascript - 带有隔离范围的 Angular 双向绑定(bind)似乎是单向的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27558552/

相关文章:

javascript - 在 React 中渲染图像

javascript - onclick函数需要执行一个简单的javascript函数

javascript - Three.js - 为什么阴影只显示在一个小区域

javascript - 如何保持我的用户脚本工作,即使网站离线?

javascript - AngularJS 在 ng-repeat 中应用分页更改类

javascript - 如何使用 Yeoman 缩小 Bower 组件?

javascript - 如何等待异步函数完成

AngularJS - 从一组过滤器对象构建过滤搜索

javascript - Angular 变量初始化

javascript - 显示当前日期 AngularJS