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

IT技术 javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat
2021-03-07 10:52:48

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

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

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

如果我们试过这个

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

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

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

  • 需要使用动态名称值
  • 需要能够调用 $scope.formName.dynamicName.$valid
  • 需要能够调用 $scope.formName.$valid
  • 需要将动态名称输入字段添加到嵌套表单或主表单
4个回答

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

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

演示

在某些情况下,如果您可以只传递信息,则内部表单是一个很好的解决方案:(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>

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

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

ngMessages 读取值与 ngShow 的方式似乎有所不同。plnkr.co/edit/clYtzWGC4CJl7xgI2UJO?p=preview我的方法适用于 ng-show,但您的方法适用于两者,因此它是一个更好的解决方案。我会更新答案。
2021-04-24 10:52:48
那意味着这两者是等价的,对吗?或者您是否在第一个选项中收到了一些错误?(我使用了一个 Angular 1.x,所以它肯定可以在那里工作。如果你在 2.x 上,他们可能已经改变了它评估事物的方式。)
2021-04-29 10:52:48
ng-show="vm.myForm['person_{{$index}}'].$invalid" 应该是 ng-show="vm.myForm['person_' + $index].$invalid" 它需要一个表达式计算结果为字符串而不是字符串
2021-04-30 10:52:48
这是一个有趣的怪癖,你认为它可能与指令优先级有关吗?我总是假设 {{ 插值优先于大多数指令,除了 ng-bind 和 likes
2021-05-02 10:52:48
角的1.x这是从角文档一个plunkr修改为使用我提出的方法plnkr.co/edit/meW6azMBI60ZiRA1GQcU?p=preview这是使用插值方法的plunkr plnkr.co/edit/ibzhEhCNPLqZCflXHLW3?p=preview你可以看到它导致 ngMessages 值没有被正确解析
2021-05-06 10:52:48

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

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

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

这是如何使用指令:

<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 中,您只需遍历对象并收集包含“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
  }
});

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

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

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

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

哦顺便说一句,AngularJS 1.3+ 中存在的更好的解决方案是什么?
2021-04-21 10:52:48
对我的嵌套情况肯定有帮助。我做了一个小更正:在checkInputFormat函数中你应该检查attrs.myName.
2021-04-30 10:52:48
2021-05-09 10:52:48
我还没有找到。我会继续寻找。
2021-05-18 10:52:48

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

如何使用:

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

不要忘记您可以使用带有字符串索引的数组表示法访问 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 哈希中的键来访问该对象。

一旦你开始编写这些通用的表单处理脚本,就会涉及更多的内容,在我看来,你最终会得到一大堆意大利面条式的代码,你可能会更好地采用不太通用的解决方案,但是那是另一个问题。