我有一个简单的表单,如下所示:
<form name="myForm">
<input name="field" ng-model="item.field"></input>
<button ng-click="save()">Save</button>
</form>
理论上,我应该能够根据表单和字段更改控制器中字段的有效性等内容,如下所示:
$scope.save = function(item) {
item.$save();
$scope.myForm.field.$setValidity("some-error",false);
};
问题在于各个级别的指令会妨碍并且可能会设置多个子范围。因此,虽然item.field
被正确渲染和链接,但我从控制器做任何事情的能力都非常有限,例如:如果我将我的部分包装在一个隐藏它的花哨的“加载”指令中并显示“加载”直到完成。
<loading>
<form name="myForm">
<input name="field" ng-model="item.field"></input>
<button ng-click="save()">Save</button>
</form>
</loading>
现在,我想要直接设置有效性的控制器不再可以访问$scope.myForm
。事实是,在可能的指令下,从不可以安全地依赖$scope.myForm
的访问权;只有一个指令可以!
@Beyers建议将表单作为save()
调用的一部分传递为<button ng-click="save(myForm)">Save</button>
,这肯定有效,但会变得很麻烦。
是否有一种真正的Angular方式可以干净利落地完成这项工作?我应该直接在控制器内重置为$pristine
,还是还有其他事情要做?
更新:
我开始怀疑这是否是正确的方法。我的控制器应该像表单上的$setValidity
一样吗?它不应该从视图中获取输入并在此基础上修改业务对象(item
),以及与服务进行交互吗?角度如何知道重置ng-dirty
或ng-invalid
进行自己的验证?
答案 0 :(得分:0)
上次我这样做时,我只是抓住了Id的表单字段并且工作正常。 使用ID,你“Angularize”它,然后你可以访问它的模型等...
像这样:
//you will need to add an id to your field.
var myInput = angular.element(document.querySelector('#myInput'));
var ngModelCtrl = myInput.controller('ngModel');
ngModelCtrl.$setValidity("some-error",false);
有角度的文档说你应该只在必要的时候这样做,他们更喜欢你使用ngModel.$validators
pipline。不幸的是,我不确定如何自己使用它,所以无法帮助你。
答案 1 :(得分:0)
问题在于各个级别的指令会妨碍并且可能会设置多个子范围。
您正在遇到标准if you don't have a dot in your model, you're doing it wrong问题。这不仅适用于ng-model,也适用于表单名称。
解决方案是确保控制器中有一个表单,例如forms
:
$scope.forms = {};
在模板中使用forms.<formName>
:
<form name="forms.myForm">
...
</form>
然后在控制器代码中访问表单,使用$scope.forms.<formName>
$scope.forms.myForm.field.$setValidity("some-error" ,false);
您的更新问题:
我的控制器是否应该像表单上的$ setValidity那样执行此操作
我会根据具体情况来解决这个问题,以便KISS。有效性通常是与服务交互的结果,并且可以与业务对象/规则相关。我想说控制器中的一些代码与验证相互作用是可以的,但是如果你的控制器有很长的责任,那么尝试将一些逻辑移入可能是一个好主意。需要ngModel
的元素的自定义指令。然后,如果需要,这些可以通过控制器设置的属性接受参数/功能。