我正在尝试将输入和一些标记包装到AngularJS指令中。
然而,据说这些字段总是经过验证,不应该是。
请查看我的示例@ http://plnkr.co/edit/TivmuqQI4Y5K56gwcadW
这里是那些不想看Plunker的人的代码
我的指示
app.directive('myInput', function() {
return {
restrict: 'E',
require: '^ngModel',
templateUrl: 'form_control.html',
scope: {
label: '@',
placeholder: '@',
name: '@',
form: '=',
ngModel: '=ngModel'
},
}
});
这是我的模板
<div class="form-group" ng-class="{'has-error': form.{{name}}.$invalid && form.{{name}}.$dirty, 'has-success': form.{{name}}.$valid }">
<label for="{{name}}" class="col-sm-2 control-label">{{label}}</label>
<div class="col-sm-10">
<input type="{{type}}" class="form-control col-sm-10" id="{{name}}" name="{{name}}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true">
</div>
</div>
这是我的index.html
<my-input ng-model="website.url" name="url" label="URL" placeholder="http://example.com" form="form"></my-input>
即使模板中的输入是必需的,该字段也会被验证,如果它是空的,则不应该是该字段。
我做错了什么?
答案 0 :(得分:0)
必填字段在DOM加载时立即无效,因为它们在有值之前无效。
此外,在您的plunker中,顶部输入为绿色,有一个有效的错觉,而较低的输入为红色,表示无效。
你不能这样做......
<div class="form-group" ng-class="{'has-error': form.{{name}}.$invalid && form.{{name}}.$dirty, 'has-success': form.{{name}}.$valid }">
问题在于表单名称字段。当你这样做时......
<input type="{{type}}" class="form-control col-sm-10" id="{{name}}" name="{{name}}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true">
name =&#34; {{name}}实际上会在表单对象中编译为name {{name}}。 〔实施例:
{{name}}: Constructor$dirty: false
$error: Object
$formatters: Array[1]
$invalid: true
$isEmpty: function (value) {
$modelValue: undefined
$name: "{{name}}"
$parsers: Array[1]...
这是从您的plunker。使用console.log($ scope.form)并查看对象。 在$ error下你会发现有两个输入这个表单引用,并且它们都不是名为&#39; url&#39;的预期输入,它们实际上是&#39;标题&#39;输入和您的指令输入&#39; {{name}}&#39;如此处所见......
form: Constructor
$addControl: function (control) {
$dirty: false
$error: Object...
$name: "title"...
$name: "{{name}}"
这是一个分叉的plunker,我已经设置了console.log表格
这表明该表单不知道任何&#39; url&#39;输入。要解决此问题,您可以为输入名称字段编写自定义指令。或者只使用我在下面写的那个。
app.directive('myName', function(){
var myNameError = "myName directive error: "
return {
restrict:'A', // Declares an Attributes Directive.
require: 'ngModel', // ngModelController.
link: function( scope, elem, attrs, ngModel ){
if( !ngModel ){ return } // if no ngModel exists for this element
checkInputFormat(attrs); // check myName input for proper formatting.
var inputName = attrs.myName.match('^\\w+').pop(); // match upto '/'
assignInputNameToInputModel(inputName, ngModel);
var formName = attrs.myName.match('\\w+$').pop(); // match after '/'
findForm(formName, ngModel, scope);
} // end link
} // end return
function checkInputFormat(attrs){
if( !/\w\/\w/.test(attrs.myName )){ // should be in format "wordcharacters/wordcharacters"
throw myNameError + "Formatting should be \"inputName/formName\" but is " + attrs.myName
}
}
function assignInputNameToInputModel(inputName, ngModel){
ngModel.$name = inputName // adds string to ngModel.$name variable.
}
function addInputNameToForm(formName, ngModel, scope){
scope[formName][ngModel.$name] = ngModel; return // add input name and input object.
}
function findForm(formName, ngModel, scope){
if( !scope ){ // ran out of scope before finding scope[formName]
throw myNameError + "<Form name=" + formName + "'> element could not be found."
}
if( formName in scope){ // found scope[formName]
addInputNameToForm(formName, ngModel, scope)
return
}
findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes
}
});
// DIRECTIVE NOTES:
// This directive is used by simply including the following HTML element:
// <input my-name="email/profileForm">.
// In the example above, the input name is "email" and the form name
// that this input would be attached to would be named "profileForm"
// Like this...
// <form name="profileForm">
// <input my-name="email/profileForm">
// </form>
// Notice this "/" dividing the input name from the form name. This directive uses the '/'
// to separate the input name from the form name.
// Although it has not been tested yet, this directive should work with multi nested forms
// as well, as the recursive search only looks for the form name that was passed in, inwhich
// to bind the ngModel to.
// In this example, other form names would be skipped.
// <form name="profileForm">
// <form name="miniFormOne">
// <form name="miniFormTwo">
// <input my-name="email/profileForm">
// </form>
// </form>
// </form>
// The above example may not be the best behavior, but was just added as an example.
使用此指令,您可以像这样使用嵌套指令输入
<input type="{{type}}" class="form-control col-sm-10" id="{{name}}" my-name="{{ variableName + '/' + yourformnamevariable }}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true">
myName指令将得到:&#34; url / form&#34;在你的情况下,然后它将添加$ name变量,它将是&#39; url&#39;到用于THAT输入的ngModel,以及搜索名为&#34; form&#34;的表单的范围。并将ndModel附加到THAT表单。该指令使用&#39; /&#39;分开名字。搜索是递归的,并且会一直运行,直到找到表单名称或错误消息为止。
当然,当您创建动态输入名称时,如何调用
formName.dynamicInputName $有效吗?因为你不知道动态输入名称是什么!!!
所以使用表单。{{name}}。$ invalid&amp;&amp; form。{{name}}。$ dirty不起作用,除非你这样做......
form.$valid && form.$dirty
但是这对每个人的输入都不起作用。你可以找出自己的方法......
我在输入
中使用另一个指令然后在我的错误中,我只是在需要ngModel之后听取ngModel,你现在可以调用ngModel。$ invalid然后设置一个变量来改变CSS。如果我有时间,我会制作一个jsFiddle并将其链接到底部。但是,您可以使用类input.ng-invalid {border-color:red;输入将是红色的,直到它们有效。
如果这不清楚,请再问一些问题......我们会得到它。
希望这个有用的