AngularJS : 当一个不同的元素改变时在指令中触发 $watch
AngularJS : Trigger $watch in directive when a different element changes
我在一个表单上有两个输入(field1
、field2
)。 field1
有一个带有 $watch
的指令,而 field2
在控制器中有一个 $watch
。 field1
在添加一个值后显示 "This has a value" 或 "This field has no value" 或 added/removed。输入原始时消息为空白。
更改 field2
会将 field1
的值更改为空白。我想要发生的是通过触发指令中的 $watch
为 field1
显示 "This field has no value"。
我的项目实际上有更复杂的计算和跨多个输入的检查,但这是我需要做的基本要点。
笨蛋:http://plnkr.co/edit/XMdDt8M34VZJw1W0hkDt?p=preview
HTML:
<form name="myForm">
<p>
<label for="field1">Field 1</label>
<input custom-validator name="field1" ng-model="item.field1" type="text" />
<span>{{errorMessage}}</span>
</p>
<p>
<label for="field2">Field 2</label>
<input name="field2" ng-model="item.field2" type="text" />
</p>
</form>
指令:
myApp.directive('customValidator', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
scope.$watch(attrs.ngModel, function() {
ngModelCtrl.$parsers.unshift(function(value) {
if (value) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
scope.$parent.errorMessage = 'This field has a value.'
} else {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.$parent.errorMessage = 'This field has no value.'
}
});
});
}
}
});
控制器:
myApp.controller('FormController', function($scope) {
$scope.item = {
field1: '',
field2: ''
};
$scope.$watch('item.field2', function(oldValue, newValue) {
if (newValue) {
$scope.item.field1 = '';
}
});
});
您需要向 $formatters
pipiline 添加函数(因为您是从控制器而不是视图更改模型 - 然后 $parsers
工作)并且 运行 如果模型脏了:
myApp.directive('customValidator', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
ngModelCtrl.$parsers.unshift(function(value) {
if (value) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
scope.errorMessage = 'This field has a value.'
} else {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.errorMessage = 'This field has no value.'
}
});
ngModelCtrl.$formatters.unshift(function(value) {
if (!value && ngModelCtrl.$dirty) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.errorMessage = 'This field has no value.'
}
});
}
}
});
我还做了一些额外的更正。首先,删除 $parent
因为您的指令与错误消息共享相同的范围。然后我更改了 $watch
函数中的参数顺序:第一个是 newValue
,第二个是 oldValue
.
我在一个表单上有两个输入(field1
、field2
)。 field1
有一个带有 $watch
的指令,而 field2
在控制器中有一个 $watch
。 field1
在添加一个值后显示 "This has a value" 或 "This field has no value" 或 added/removed。输入原始时消息为空白。
更改 field2
会将 field1
的值更改为空白。我想要发生的是通过触发指令中的 $watch
为 field1
显示 "This field has no value"。
我的项目实际上有更复杂的计算和跨多个输入的检查,但这是我需要做的基本要点。
笨蛋:http://plnkr.co/edit/XMdDt8M34VZJw1W0hkDt?p=preview
HTML:
<form name="myForm">
<p>
<label for="field1">Field 1</label>
<input custom-validator name="field1" ng-model="item.field1" type="text" />
<span>{{errorMessage}}</span>
</p>
<p>
<label for="field2">Field 2</label>
<input name="field2" ng-model="item.field2" type="text" />
</p>
</form>
指令:
myApp.directive('customValidator', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
scope.$watch(attrs.ngModel, function() {
ngModelCtrl.$parsers.unshift(function(value) {
if (value) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
scope.$parent.errorMessage = 'This field has a value.'
} else {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.$parent.errorMessage = 'This field has no value.'
}
});
});
}
}
});
控制器:
myApp.controller('FormController', function($scope) {
$scope.item = {
field1: '',
field2: ''
};
$scope.$watch('item.field2', function(oldValue, newValue) {
if (newValue) {
$scope.item.field1 = '';
}
});
});
您需要向 $formatters
pipiline 添加函数(因为您是从控制器而不是视图更改模型 - 然后 $parsers
工作)并且 运行 如果模型脏了:
myApp.directive('customValidator', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
ngModelCtrl.$parsers.unshift(function(value) {
if (value) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
scope.errorMessage = 'This field has a value.'
} else {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.errorMessage = 'This field has no value.'
}
});
ngModelCtrl.$formatters.unshift(function(value) {
if (!value && ngModelCtrl.$dirty) {
ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
scope.errorMessage = 'This field has no value.'
}
});
}
}
});
我还做了一些额外的更正。首先,删除 $parent
因为您的指令与错误消息共享相同的范围。然后我更改了 $watch
函数中的参数顺序:第一个是 newValue
,第二个是 oldValue
.