【问题标题】:dynamically naming input controls in angularjs在angularjs中动态命名输入控件
【发布时间】:2014-05-25 14:17:35
【问题描述】:

我有一个我想动态命名的输入元素,但到目前为止我没有运气使用 angular js。

都没有

<input type="text" name="resource.Name" ng-model="resource.Value" ng-required="resource.IsRequired">

也没有

<input type="text" name="{{resource.Name}}" ng-model="resource.Value" ng-required="resource.IsRequired">

为我工作。当我尝试访问 name 属性时,它总是作为 resource.Name 而不是它包含的值返回。我试图命名这个输入控件的主要原因是验证,如果用户没有在字段中输入文本,我想告诉他们需要哪个文本框。如果有任何角度指令我可以用于此目的,我也准备好使用它们。

谁能告诉我如何做到这一点。

我的验证函数如下:

 window.resourcesValidation = function ($scope, $rootScope, $alert) {
        var subscriptions = $scope.scopeData.Subscriptions;
        var isValidated = true;

        if ($scope.resourceDataForm && $scope.resourceDataForm.$error && $scope.resourceDataForm.$error.required) {
            var missingFields = [];
            angular.forEach($scope.resourceDataForm.$error.required, function (value, key) {
                isValidated = false;
                missingFields.push("-" + value.$name);
            });

            $alert.error("Please fill in the all required fields.\r\n" + missingFields.join("\r\n"));
        }

        if (isValidated)
            $scope.saveChanges(subscriptions);

        return isValidated;
    };

【问题讨论】:

  • $scope.resourceDataForm 是什么样的?你有机会用 plunker 或其他东西做一个演示吗?
  • 为什么要将 resourcesValidation 放在全局函数中,而不是放在模块的控制器中?
  • 在resourcesValidation函数中下断点,查看$scope.resourceDataForm$scope.resourceDataForm.$error.required 是一个数组吗?它的项目是否具有$name 属性?你能发布整个对象的样子吗?
  • 是的,Jerrad 那是一个数组。第一个元素有一个 $name 属性,它具有以下值:{{subscriptionResource.Name}},我认为 angularjs 的 ng-required 验证在绑定之前使用控件的名称。

标签: javascript angularjs input angularjs-directive


【解决方案1】:

试试这个:

<input type="text" ng-attr-name="{{resource.Name}}" ng-model="resource.Value" ng-required="resource.IsRequired">

来自docs

如果具有绑定的属性以 ngAttr 前缀(非规范化为 ng-attr-)作为前缀,则在绑定期间将应用于相应的无前缀属性。

虽然name="{{resource.Name}}" 在这种情况下也应该可以工作。

更新

我在这里找到了解决方案:Dynamic validation and name in a form with AngularJS

这是我制作的plunker

听起来这个问题可能会在 Angular 1.3 中得到修复。

【讨论】:

  • 它可以工作,但我仍然无法在我的验证函数中正确访问控件的名称。
  • 这是一个单独的问题。我们可以看看你的验证函数吗?
  • 我刚刚发布在原来的问题中。
  • 也许您可以添加一些信息,为什么您以这种方式更改原始代码,以便未来的读者可以理解并解决与此类似的问题。
  • 原来的问题只是问如何绑定name属性。我的回答为此提供了解决方案。在我回答之前,他们没有添加关于验证功能的内容。
【解决方案2】:

在非常相似的问题上引用另一个答案:

发生这种情况是因为在ngModelController 的实例化过程中检索了控件的名称(它在其父窗体上注册的名称),这according to the docs 发生在前链接阶段*(所以还没有插值)。


换句话说,验证依赖于forms.$error 对象,该对象绑定到使用该表单注册的控件。
控件的ngModelController 负责将控件注册到其父窗体,并在预链接阶段(此时尚未插入名称表达式)进行实例化。

这可以通过一个自定义指令来解决,该指令手动将控件注册到其父窗体,但只有在确定了它的实际名称之后(在插入名称表达式之后)。


您可以找到完整的答案here
UPDATE 2 部分寻找可行的解决方案。

(这是 working demo 的链接。)

【讨论】:

  • 非常感谢,这似乎是我的问题。我会试一试,让你知道ç
【解决方案3】:

你能展示你的其余代码吗? (HTML、相关控制器等)

有时问题可能围绕异步进行。例如,在您的$scope.resource 对象获取其数据之前,Angular 的编译器可能会编译 HTML(可能通过 AJAX 调用)。

双向数据绑定有时并不总是如您所愿。因此,在使用任何函数将数据“放入”$scope.resource 之后,您可能需要调用 $scope.$apply()

【讨论】:

  • 我认为我的问题在于我的验证功能,我现在发布它。
【解决方案4】:
<input ng-model="resource.model" name="{{resource.name}}" ng-required="{{resource.required}}"/>

似乎对我有用。请看这个 plnkr

【讨论】:

    【解决方案5】:

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

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

    我有一个包含多嵌套指令的表单,所有指令都包含输入、选择等... 这些元素都包含在 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 中,您只需遍历对象并收集包含“hello”的任何键即可找到任何表单输入名称。

    app.directive('rsName', function(){
    
      var rsNameError = "rsName 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 rsName input for proper formatting ex. something/something
          checkInputFormat(attrs);
    
          var inputName = attrs.rsName.match('^\\w+').pop(); // match upto '/'
          assignInputNameToInputModel(inputName, ngModel);
    
          var formName = attrs.rsName.match('\\w+$').pop(); // match after '/'
          findForm(formName, ngModel, scope);
        } // end link
      } // end return
    
      function checkInputFormat(attrs){
        if( !/\w\/\w/.test(attrs.rsName )){
          throw rsNameError + "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 rsNameError + "<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+ 中。我当时找不到。现在这对我有用。

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

    【讨论】:

      猜你喜欢
      • 2021-01-15
      • 1970-01-01
      • 2015-01-23
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多