Javascript Angularjs中的动态表单名称属性<input type="text" name="{{ variable-name }}" />

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27071413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:40:29  来源:igfitidea点击:

Dynamic form name attribute <input type="text" name="{{ variable-name }}" /> in Angularjs

javascriptangularjsangularjs-directiveangularjs-scopeangularjs-ng-repeat

提问by SoEzPz

How would someone use formName.inputName.$valid when the "inputName" was dynamically created?

当动态创建“inputName”时,有人如何使用 formName.inputName.$valid ?

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

The output of the HTML input attribute 'name' would be the string "variablename", which would applied to ALL repeated inputs.

HTML 输入属性“name”的输出将是字符串“variablename”,它将应用于所有重复输入。

If we tried this

如果我们试过这个

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

The output of the HTML input attribute 'name' would be the string"{{ variable.name }}", which would be applied to ALL repeated inputs.

HTML 输入属性 'name' 的输出将是字符串“{{ variable.name }}”,它将应用于所有重复输入。

In either of these two conditions, a name attribute for each of the repeated input elements would not be created dynamically; ALL inputs would share the same input name. Not much good if you wanted to call a specific input based on a specific name.

在这两种情况中的任何一种情况下,都不会动态创建每个重复输入元素的名称属性;所有输入将共享相同的输入名称。如果您想根据特定名称调用特定输入,那就没什么好处了。

  • need to use dynamic name values
  • need to be able to call $scope.formName.dynamicName.$valid
  • need to be able to call $scope.formName.$valid
  • need dynamic name input fields to be added to nested form, or master form
  • 需要使用动态名称值
  • 需要能够调用 $scope.formName.dynamicName.$valid
  • 需要能够调用 $scope.formName.$valid
  • 需要将动态名称输入字段添加到嵌套表单或主表单

采纳答案by SoEzPz

I could not find the answer that satisfied some or all of these needs. This is what I came up with.

我找不到满足部分或所有这些需求的答案。这就是我想出的。

There may be a better way, so please share your thoughts.
I am using Angularjs 1.3.0-beta.8

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

I have a form with multi-nested directives that all contain input(s), select(s), etc... These elements are all enclosed in ng-repeats, and dynamic string values.

我有一个带有多嵌套指令的表单,所有指令都包含输入、选择等……这些元素都包含在 ng-repeat 和动态字符串值中。

This is how to use the directive:

这是如何使用指令:

<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>

Note: you can add and index to the string concatenation if you need to serialize perhaps a table of inputs; which is what I did. However, dynamic name inputs means you may not know the name of the form input, so how would you call $scope.formName.??????. You could iterate of the $scope.formName object to get keys that match a certain value. That means string concatenation like this:

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

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

Then in $scope.myFormName you would find any form input name by just iterating over the object and gathering any keys that included 'hello'.

然后在 $scope.myFormName 中,您只需遍历对象并收集包含“hello”的任何键即可找到任何表单输入名称。

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
  }
});

This should handle many situations where you just don't know where the form will be. Or perhaps you have nested forms, but for some reason you want to attach this input name to two forms up? Well, just pass in the form name you want to attach the input name to.

这应该可以处理许多您不知道表单在哪里的情况。或者,您可能有嵌套的表单,但出于某种原因,您想将此输入名称附加到两个表单上?好吧,只需传入要附加输入名称的表单名称。

What I wanted, was a way to assign dynamic values to inputs that I will never know, and then just call $scope.myFormName.$valid.

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

This may be an overkill, and a better solution exists in 1.3+. I couldn't find it in the time I had. This works for me now.

这可能有点矫枉过正,1.3+ 中存在更好的解决方案。我在我有的时候找不到它。这现在对我有用。

Good luck! Hope this helps someone!!!!

祝你好运!希望这对某人有所帮助!!!!

回答by Loren

Looks like Angular 1.3 fixed this (https://stackoverflow.com/a/32907176/3854385)

看起来 Angular 1.3 修复了这个问题(https://stackoverflow.com/a/32907176/3854385

This is now possible with Angular 1.3+:

现在可以使用 Angular 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

演示

In some cases an inner form is a good solution if you can just pass the information: (https://stackoverflow.com/posts/12044600/) To solve the 'dynamic name' problem you need to create an inner form (see ng-form):

在某些情况下,如果您可以传递信息,则内部表单是一个很好的解决方案:(https://stackoverflow.com/posts/12044600/)要解决“动态名称”问题,您需要创建一个内部表单(参见ng -形式

<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>

The other alternative would be to write a custom directive for this.

另一种选择是为此编写自定义指令。

Here is the jsFiddle showing the usage of the ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

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

回答by Sergey Karasev

work for me with angular 1.2.7

angular 1.2.7为我工作

directive:

指示:

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>

回答by fluoresce

Don't forget that you can access javascript objects using array notation with string indexes. Given the following arbitrary form definition object :

不要忘记您可以使用带有字符串索引的数组表示法访问 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 = {};

... and the html snippet ...

...和 ​​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>

Inside the controller you then would have a nice form_values object for every field which you can access by iterating over the keys in the form_def.variables hash.

在控制器内部,您将为每个字段都有一个不错的 form_values 对象,您可以通过遍历 form_def.variables 哈希中的键来访问该对象。

There is a lot more involved once you get down into writing these sort of generic form processing scripts and you end up with a hell of a lot of spaghetti code in my opinion and you would probably be better of going with a less general solution, but thats another SO question.

一旦你开始编写这些通用的表单处理脚本,并且在我看来你最终得到了大量的意大利面条代码,你可能会更好地使用一个不太通用的解决方案,但是那是另一个问题。