2014-12-19 36 views
1

我已经编写了一个简单的点击编辑指令,使用隔离范围以便可重用。当我使用它时,控制器作用域中的源值('=')永远不会更新,尽管其原始值在该指令中应用。就好像绑定是单向的('@')。角度双向绑定与隔离范围似乎是单向的

下面的代码:

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); 
      }; 
     }, 
    }; 
}); 

这里是在控制器调用(编辑以ng-如果DIV块包裹):

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

当validateName()在控制器范围调用'name'的值是原始值,而不是指令输入控件中的(更改)值。该模型未更新。为什么?

解决: 的NG-如果块创建一个子范围,传递name作为字符串原始由于prototypal inheritance。将对象引用传递给指令解决了这个问题。在这里看到一个revised plunker

回答

0

这是因为外部示波器的name尚未分配到内部示波器的source。当您声明隔离范围为"="时,Angular $watch适用于两个值中的更改(请参阅code),并执行双向绑定,但在调用validator时$ watch尚未触发。

您可以使用此代码检查:

$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)你可以$腕表在source更改,然后火$validator(而不是ng-change):

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

3)你可以通过验证进入验证函数值:

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

感谢您的评论。但是我意识到我忽略了提及控制器值_never_发生变化,所以我不认为这是一个计时问题。每次调用后,它始终是原始值,就好像指令中的$ watch不会更新源。有什么想法? – John 2014-12-19 03:59:32

+0

将代码复制到[plunker](http://plnkr.co/edit/fHHbCEuKA1eBQyzATKaD?p=preview)时发生了变化。你可以创建一个蹲点来重现你的问题吗? – 2014-12-19 04:00:21

+0

这里是你测试的输出: 外部指令:name = nnnnm 但是在摘要循环之后:name = nnnnm – John 2014-12-19 04:06:00