21

当“inputName”动态创建时,他人如何使用formName.inputName。$ valid?Angularjs中的动态表单名称属性<input type =“text”name =“{{variable-name}}”/>

<form name="formName"> 
    <input ng-repeat="(variable) in variables" 
      type="text" name="variable.name" 
      ng-model="variable.name" required /> 
</form> 

HTML输入属性“名称”的输出将是字符串“VARIABLENAME”,这将适用于所有的重复的输入。

如果我们试图此

<form name="formName"> 
    <input ng-repeat="(variable) in variables" 
     type="text" name="{{ variable.name }}" 
     ng-model="variable.name" required /> 
</form> 

HTML输入属性“名称”的输出将是字符串“{{variable.name}}”,这将适用于所有的重复的输入。

在这两个条件中的任何一个中,每个重复输入元素的名称属性都不会动态创建;所有输入将共享相同的输入名称。如果您想根据特定的名称调用特定的输入,则效果并不好。

  • 需要使用动态域名值
  • 需要能够调用$ scope.formName.dynamicName。$有效
  • 需要能够调用$ scope.formName。$有效
  • 需要要添加到嵌套窗体或主窗体的动态名称输入字段
+0

http://stackoverflow.com/questions/21455695/angularjs-dynamic-form-field-validation/21457121#21457121 – 2015-06-06 04:29:09

回答

1

我无法找到满足部分或全部这些需求的答案。这是我想出的。

可能有更好的方法,请分享您的想法。
我使用Angularjs 1.3.0-beta.8

我与多嵌套指令,所有包含输入(S)形式,选择(一个或多个),等... 这些元件都包含在ng-repeats和动态字符串值。

这是如何使用的指令:

<form name="myFormName"> 
    <nested directives of many levels> 
    ex: <input ng-repeat=(index, variable) in variables" type="text" 
       my-name="{{ variable.name + '/' + 'myFormName' }}" 
       ng-model="variable.name" required /> 
    ex: <select ng-model="variable.name" ng-options="label in label in {{ variable.options }}" 
       my-name="{{ variable.name + '/' + 'myFormName' }}" 
     </select> 
</form> 

注意:你可以,如果你需要或许序列化的输入表中添加和指数的字符串连接;这就是我所做的。但是,动态名称输入意味着您可能不知道表单输入的名称,那么您将如何调用$ scope.formName。??????。您可以迭代$ scope.formName对象以获得匹配特定值的键。这意味着字符串连接这样的:

my-name="{{ dynamicString + hello + '/' + 'myFormName' }}" 

然后在$ scope.myFormName则可以通过将只是遍历对象和收集,包括“你好”的任何键找到任何形式的输入名称。

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 } // no ngModel exists for this element 

     // check myName input for proper formatting ex. something/something 
     checkInputFormat(attrs); 

     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.rsName)){ 
     throw myNameError + "Formatting should be \"inputName/formName\" but is " + attrs.rsName 
    } 
    } 

    function assignInputNameToInputModel(inputName, ngModel){ 
    ngModel.$name = inputName 
    } 

    function addInputNameToForm(formName, ngModel, scope){ 
    scope[formName][ngModel.$name] = ngModel; return 
    } 

    function findForm(formName, ngModel, scope){ 
    if(!scope){ // ran out of scope before finding scope[formName] 
     throw myNameError + "<Form> element named " + formName + " 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 
    } 
}); 

这应该处理很多情况下,你只是不知道窗体将在哪里。或者您可能嵌套了表单,但出于某种原因,您希望将此输入名称附加到两个表单中?那么,只需传入您想要附加输入名称的表单名称即可。

我想要的是一种将动态值分配给我永远不会知道的输入的方法,然后调用$ scope.myFormName。$ valid。

这可能是一个矫枉过正的问题,1.3+中存在更好的解决方案。我无法在我的时间找到它。这现在适合我。

祝你好运!希望这可以帮助别人!

+0

肯定与我的嵌套的情况有帮助。我做了一个小小的更正:在'checkInputFormat'函数中,您应该检查'attrs.myName'。 – 2014-12-26 15:09:13

+0

哦,顺便说一句,AngularJS 1.3+中有更好的解决方案吗? – 2014-12-26 15:26:05

+0

我还没有找到它。我会继续寻找。 – SoEzPz 2014-12-26 17:29:19

-1

不要忘记,您可以使用数组符号和字符串索引访问JavaScript对象。鉴于以下任意形式定义对象:

$scope.form_def = { 
    form_name : 'BallForm', 
    variables : [ 
    height : { name : 'Height', type : 'text' }, 
    width : { name : 'Width', type : 'text' }, 
    color : { name : 'Color', type : 'multi', options : ['red', 'green', 'blue'] } 
    ] 
}; 
$scope.form_values = {}; 

...和HTML片段...

<form name="{{ form_def.form_name }}"> 
    <div ng-repeat="variable in form_def.variables"> 
    <input ng-if="variable.type==='text'" type="text" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
    <select ng-if="variable.type==='multi'" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
     <option ng-repeat="opt in variable.options" value="{{ opt }}">{{ opt }}</option> 
    </select> 
    </div> 
</form> 

控制器内部,你会再有一个很好的form_values对象,而您可以访问各个领域通过迭代form_def.variables散列中的键。

一旦你开始编写这些通用的表单处理脚本,并且在我看来最终会有很多意大利面代码的地狱,并且你可能会更好地使用更少的代码一般的解决方案,但那是另一个SO问题。

16

看起来像固定角1.3本(https://stackoverflow.com/a/32907176/3854385

这现在是可能的角1.3+:

<form name="vm.myForm" novalidate> 
    <div ng-repeat="p in vm.persons"> 
    <input type="text" name="person_{{$index}}" ng-model="p" required> 
    <span ng-show="vm.myForm['person_' + $index].$invalid">Enter a name</span> 
    </div> 
</form> 

Demo

在一些情况下的内形式是一个很好的解决方案如果您只能传递以下信息:(https://stackoverflow.com/posts/12044600/) 要解决'动态名称'问题您需要d创建的内表(见ng-form

<div ng-repeat="social in formData.socials"> 
     <ng-form name="urlForm"> 
      <input type="url" name="socialUrl" ng-model="social.url"> 
      <span class="alert error" ng-show="urlForm.socialUrl.$error.url">URL error</span> 
      <button ng-click="doSomething(urlForm.socialUrl.$valid)">Test</button> 
     </ng-form> 
    </div> 

另一替代方案将是写此自定义指令。

这里是的jsfiddle显示ngForm的用法:http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

+1

ng-show =“vm.myForm ['person _ {{$ index}}'] 。$ invalid“应该是ng-show =”vm.myForm ['person_'+ $ index]。$ invalid“它需要一个表达式来计算一个字符串而不是一个字符串 – 2016-12-29 20:52:24

+0

这意味着这两个值相等, ?或者您是否收到第一个选项的错误? (我使用了Angular 1.x,所以它应该可以在那里工作,如果你使用的是2.x,它们可能改变了它的评估方式。) – Loren 2016-12-29 21:01:45

+0

Angular 1.x这是一个从角度文档修改为使用的plunkr我建议的方法https://plnkr.co/edit/meW6azMBI60ZiRA1GQcU?p=preview这是一个使用插值方法https://plnkr.co/edit/ibzhEhCNPLqZCflXHLW3?p=preview的plunkr,你可以看到它导致ngMessages值没有被正确解析 – 2016-12-29 21:07:41

0

工作,角1.2.7

指令:

var DynamicName = function() { 
    return { 
     restrict: 'A', 
     priority: -1, 
     require: ['ngModel'], 
     link: function (scope, element, attr, ngModel) { 
      ngModel[0].$name = attr.name; 
     } 
    }; 
}; 

app.directive('dynamicName', DynamicName); 

howtouse:

<div ng-repeat="phone in hrModel.phones"> 
    <input type="text" 
      name="phones[{{$index}}]" 
      ng-model="phones[$index]" 
      dynamic-name 
    /> 
</div> 
0

编译你的输入名称

  1. 正如别人指出的,棱角分明的现代版本有固定的这个...
  2. 这应该设置在您输入的name属性,以及模型控制器添加到窗体:
 
    angular.module('MOD') 
     .directive('compiledName', compiledNameDirective); 

    function compiledNameDirective() { 
     return { 
      restrict: 'A', 
      require: ['ngModel', '?^form'], 
      scope: { 
       name: '@compiledName' 
      }, 
      link: function checkboxIndeterminateLink(scope, element, attributes, required) { 
       var ngModelController = required[0], ngFormController = required[1]; 
       ngModelController.$name = scope.name; 
       element.attr('name', scope.name); 
       if (ngFormController) ngFormController.$addControl(ngModelController); 
      } 
     }; 
    } 


    

相关问题