我在其中一个指令中使用ctrl.$setValidity
来使表单无效。但是,有一种驻留在其他地方的方法可以在不同的条件下从DOM中删除该元素。当我使用$setValidity
使表单无效然后删除有问题的元素时,会发生什么?表单仍然无效,而我希望它根据新的Inputfield集重新计算其有效性。
请注意,我不只是在寻找ctrl.$setValidity true
,(表单中的其他输入字段可能有效也可能无效),我只是希望重新计算表单。
以下是指令代码:
app.directive('dir', function() {
return {
restrict: 'C',
require: "ngModel",
link: function(scope, element, attrs, ctrl) {
someValue = scope.someValue;
someField = element.find(".some-class");
monitorField = function(newValue, oldValue){
console.log("whee");
scope.someFunction(newValue);
if(newValue =="Invalidate NOW!"){
ctrl.$setValidity('someClass', false);
} else if (oldValue == "Invalidate NOW!"){
angular.element(document.querySelector('.some-class')).remove();
} else {
ctrl.$setValidity('someClass', true);
}
}
scope.$watch("someValue", monitorField, true);
}
}
});
其中包括:
<FORM class="dir" ng-model="someValue">
<INPUT type="text" class="some-class" ng-model="someValue"/>
<INPUT type="text" class="some-other-class"/>
</FORM>
(是的,这是一个有点人为的例子)。
问题转载于此:http://jsfiddle.net/kTuAY/
在我的实际代码中,我根据一个对象数组填充输入字段,这些对象通过Service填充,并通过array.splice删除元素。 jsfiddle中给出的例子仅仅是为了简单起见。
另一个有趣的失败条件可以在这个小提琴中看到:
具体来说,如果其中一个输入依赖于值与另一个的非冲突,并且因此无效,那么其他字段值改变之后,有效性仍然不正确。
上班时临时不太正常的小提琴:
谢谢!
答案 0 :(得分:2)
删除链接到模型部分的DOM元素应该通过删除模型指向的$ scoped对象的一部分来完成(如果可能)。想想基本的ngRepeat,如果从数组中删除一个项目,它会从DOM中删除一个元素。您的表单应该以相同的方式工作。这样可以防止这种情况发生。所有验证信息都包含在$ scope中的模型中......例如:$scope.myForm.model.$error.required
。如果删除模型所指向的$ scope属性或数组项(例如$scope.foo
或$scope.items.splice(2,1)
,Angular将知道(可能在下一个$摘要期间)去除模型以及这是验证信息。
如果删除控制器或指令中的项目无关紧要,但应该从$ scope中删除它,然后需要为UI进行摘要并验证更新。
我希望有所帮助,因为我觉得我偶然发现了我想说的话......
答案 1 :(得分:0)
我认为问题不在指令中,而是在“其他”代码中
如果在对“本机”事件的响应中完成DOM元素移除 - 即拖放事件,ajax事件或某事,则角度框架将不知道自己运行重新计算。在完成更新后的代码中,您必须在适当的范围内调用$ scope。$ apply()。
哦,我看到你的小提琴......好吧。如何让生活变得更轻松 - 而不是删除你的DOM元素为什么不用ng-show属性来装饰它并让角度照顾其余的?
答案 2 :(得分:0)
我最终解决这个问题的方式是:
ng-repeated
上放置一个单独的监视表达式。.val()
强制重置这些字段的值,然后在内部字段上调用$compile
以重新触发内部监视表达式ctrl.$setValidity
之前从内部指令调用的函数:
好处:
$digest
的数量将加倍
我会在清理代码后立即编写一个代码示例。