我有一个带有服务器端验证的表单。如果服务器返回验证错误,我想在表单中显示它们,但只有在用户编辑任何内容之前。
理想情况下,我希望有类似的内容:
<form name='MyForm' ng-submit='doSomething()'>
<label for='my-field-id'>Some field</label>
<input type='text' id='my_field_id' ng-model='myField' name='my_field'>
<div ng-show-if-changed='MyForm.my_field.serverSideError'
ng-show-until='MyForm.my_field.changed'>Error!</div>
</form>
如何实现这种行为?我真的想避免将这个逻辑放在一个控制器中,并希望提出一些聪明的可重用指令。
这里主要是如何实现ng-show-until-changed
功能。它的逻辑必须是“如果显示一个元素并且目标被改变 - 隐藏它”。这里的问题是:
MyForm.my_field.serverSideError
- 我可能需要在更改时手动启动$digest
吗?例如,在AJAX请求完成后,可能会有一些错误从服务器到达?如何正确监视这些服务器端错误的变化?ng-show
指令相同的方式隐藏/显示自定义指令中的某个元素的正确方法是什么?是否有一些内置的实用工具?答案 0 :(得分:0)
最简单和最原始的方法是在表单中添加一个文本框,并将其设置为只读,这样用户就无法对其执行任何操作。但您仍然可以使用JavaScript将文本放入框中,例如从服务器获取的错误消息。当然,您可以随时擦除文本(例如,由用户编辑的数据输入字段的onkeydown
事件处理程序触发)。
类似且更优雅的方式涉及表单HTML中的<p>
元素,位于您希望用户进行某些编辑的位置附近:
<p id="errmsg"> </p>
在你的Javascript中你会做这样的事情,准备:
var P=document.getElementById("errmsg");
然后,当您需要从服务器显示错误消息时:
P.innerHTML="Text of error message";
当用户开始编辑时(再次使用onkeydown
事件处理程序进行检测),您可以将错误消息文本替换为另一个
如果你真的想隐藏/显示错误信息,你可以考虑构建几个段落,所有段落都有相同的行数。每个都包含预先写好的错误消息,尽管其中一个可能是关于应该输入的数据的指令。这是默认显示的那个。所有段落都可以堆叠在表单的相同位置,这样:
<div style="position:relative;">
<p id="p1" style="position:absolute;top='0px';left='0px';" hidden="">paragraph 1 text</p>
<p id="p2" style="position:absolute;top='0px';left='0px';" hidden="hidden">paragraph 2</p>
<p id="p3" style="position:absolute;top='0px';left='0px';" hidden="hidden">paragraph 3</p>
</div>
<br /> <!-- you will discover that some line-breaks are needed here -->
<br />
您将再次使用JavaScript来获取每个段落的getElementById(),或许可以使用P []变量数组。然后,您可以使用
隐藏或显示任何段落P[x].hidden="hidden";
P[x].hidden="";
答案 1 :(得分:0)
您可以在模型更改时隐藏错误消息,并在提交时出现错误时再次显示错误消息。 请参阅下面的示例或[plunker] [1]
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
</head>
<body ng-app="changeExample">
<!-- snippet adapted from https://docs.angularjs.org/api/ng/directive/ngChange. -->
<script>
angular.module('changeExample', [])
.controller('ExampleController', [
'$scope',
function($scope) {
var model;
function simulateError(model) {
model.hasError = true;
model.errorMessage = "Some validation error!"
}
$scope.model = model = {
myField: 'my field value',
hasError: false,
errorMessage: '',
changed: false
};
$scope.change = function() {
model.hasError = false; // soon as the model changes unset the error.
};
$scope.doSomething = simulateError;
}
]);
</script>
<!--
snippet adapted from SO question
NOTES:
- using ng-change to listen to input field changes
- ng-trim="false" to listen to whitespace e.g spacebar
- hide error when user uses text input field
-->
<form name="myForm" ng-controller="ExampleController" ng-submit="doSomething(model)">
<label for="my-field-id">Fill in:</label>
<input type="text" id="my_field_id" ng-model="model.myField" ng-change="change()" ng-trim="false" />
<input type="submit" />
<div ng-show="model.hasError" ng-bind="model.errorMessage">
Error from server goes here!
</div>
</form>
</body>
</html>
&#13;