我使用隔离范围编写了一个简单的点击编辑指令,以便它可以重复使用。当我使用它时,控制器范围中的源值(' =')永远不会更新,尽管它的原始值在指令中应用。它好像绑定是单向的(' @')。
以下是代码:
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-if div块中):
<div ng-if='name'>
<ng-click-to-edit validator='validateName()' source='name' />
</div>
当调用控制器范围中的validateName()时,将调用&#39; name&#39;的值。是指令输入控件中的原始值而不是(已更改)值。该模型未更新。为什么呢?
解决:
ng-if块创建子范围,由于prototypal inheritance而将name
作为字符串原语传递。将对象引用传递给指令可以解决问题。请在此处查看revised plunker。
答案 0 :(得分:0)
这是因为外部范围name
尚未分配内部范围source
。当您使用"="
声明隔离范围时,Angular $watch
会在两个值中进行更改(请参阅code),并执行双向绑定,但$ watch避难所&t在调用validator
时被解雇。
您可以使用以下代码进行检查:
$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})"..>