首页 > 解决方案 > 使用 AngularJS Material 在 AngularJS 中动态删除元素时重新验证表单

问题描述

我有一个用 AngularJS Material 元素制作的表单,可以在其中动态添加和删除元素。这些元素中的每一个都由一个 md-autocomplete 和一个输入组成。这两个字段都是必需的。我有两个问题,第一个是输入没有正确验证,第二个问题是当一个字段被删除时,表单没有重新验证,所以即使那个时刻的元素是无效的,表单也会被认为是无效的正确填写。我不知道为什么不验证输入,也不知道每次添加或删除元素时如何重新评估表单。这是表单的外观:

这就是表单的外观。

动态添加的元素是这样的:

<div id="campoExtra${$scope.nCampoExtra}" style="max-height: 95px;">
<md-input-container flex="50"> +
    <md-autocomplete required="required" md-no-cache="noCache" md-input-name="atributoExtra${$scope.nCampoExtra}" md-input-id="searchinput" md-selected-item="selectedItem[${$scope.nCampoExtra}]" md-search-text-change="searchTextChange(searchText[${$scope.nCampoExtra}])" md-search-text="searchText[${$scope.nCampoExtra}]" md-selected-item-change="selectedItemChange(item)" md-items="item in querySearch(searchText[${$scope.nCampoExtra}])" md-item-text="item.display" md-min-length="0" md-floating-label="Atributo extra ${$scope.nCampoExtra}">
        <md-item-template style="color: #9ea1a4;">
            <span md-highlight-text="searchText[${$scope.nCampoExtra}]" md-highlight-flags="^i">{{item.display}}</span>
        </md-item-template>
        <md-not-found ng-hide="extraCreado">
        <md-button ng-hide="extraCreado" ng-click="crearCampoExtra(searchText[${$scope.nCampoExtra}], ${$scope.nCampoExtra})" style="width: 100%; text-align: center;">Crear!</md-button></md-not-found>
        <div ng-messages="formAtributosExtra.atributoExtra${$scope.nCampoExtra}.$error" ng-if="formAtributosExtra.atributoExtra${$scope.nCampoExtra}.$touched">
            <div ng-message="required">Campo requerido</div>
        </div>
    </md-autocomplete>
</md-input-container>
<md-input-container flex="50">
    <label>Valor atributo extra ${$scope.nCampoExtra}</label>
    <input name="atributosExtraValor${$scope.nCampoExtra}" ng-model="atributosExtraValor[${$scope.nCampoExtra}]" required>
    <div ng-messages="formAtributosExtra.atributosExtraValor${$scope.nCampoExtra}.$error">
        <div ng-message="required">This field is required.</div>
    </div>
</md-input-container>

插入元素的形式如下:

<form name="formAtributosExtra" ng-submit="actualizarAtributos()" >
<div layout="row">
    <md-button class="md-fab md-mini" aria-label="Añadir campo" ng-click="crearCampo()" >
        <md-icon md-svg-src="img/icons/add.svg"></md-icon>
    </md-button>
    <md-button class="md-fab md-mini" aria-label="Quitar campo" ng-click="quitarCampo()" >
        <md-icon md-svg-src="img/icons/remove.svg"></md-icon>
    </md-button>
</div>
<div layout="column" id="camposExtra"></div>

添加和删​​除字段的功能是:

  //Add field
  $scope.crearCampo = function () {
    let template = `<div id="campoExtra${$scope.nCampoExtra}" style="max-height: 95px;">`+
                      `<md-input-container flex="50">` +
                      `<md-autocomplete required="required" md-no-cache="noCache" md-input-name="atributoExtra${$scope.nCampoExtra}" md-input-id="searchinput" md-selected-item="selectedItem[${$scope.nCampoExtra}]" md-search-text-change="searchTextChange(searchText[${$scope.nCampoExtra}])" md-search-text="searchText[${$scope.nCampoExtra}]" md-selected-item-change="selectedItemChange(item)" md-items="item in querySearch(searchText[${$scope.nCampoExtra}])" md-item-text="item.display" md-min-length="0" md-floating-label="Atributo extra ${$scope.nCampoExtra}">`+
                        `<md-item-template style="color: #9ea1a4;">`+
                          `<span md-highlight-text="searchText[${$scope.nCampoExtra}]" md-highlight-flags="^i">{{item.display}}</span>`+
                        `</md-item-template>`+
                        `<md-not-found ng-hide="extraCreado">`+
                        `<md-button ng-hide="extraCreado" ng-click="crearCampoExtra(searchText[${$scope.nCampoExtra}], ${$scope.nCampoExtra})" style="width: 100%; text-align: center;">Crear!</md-button></md-not-found>`+
                        `<div ng-messages="formAtributosExtra.atributoExtra${$scope.nCampoExtra}.$error" ng-if="formAtributosExtra.atributoExtra${$scope.nCampoExtra}.$touched">`+
                        `<div ng-message="required">Campo requerido</div>`+
                        `</div>`+
                      `</md-autocomplete>`+
                      `</md-input-container>`+
                      `<md-input-container flex="50">`+
                        `<label>Valor atributo extra ${$scope.nCampoExtra}</label>`+
                        `<input name="atributosExtraValor${$scope.nCampoExtra}" ng-model="atributosExtraValor[${$scope.nCampoExtra}]" required>`+
                        `<div ng-messages="formAtributosExtra.atributosExtraValor${$scope.nCampoExtra}.$error">`+
                          `<div ng-message="required">This field is required.</div>`+
                        `</div>`+
                      `</md-input-container>`+
                    `</div>`;
    let html = $compile(template)($scope);
    angular.element(document.getElementById("camposExtra")).append(html);
    $scope.nCampoExtra++;
  };

  //Delete last field
  $scope.quitarCampo = function () {
    if ($scope.nCampoExtra > 1) {
      let nCampoExtra = $scope.nCampoExtra - 1;
      angular.element(document.getElementById("campoExtra" + nCampoExtra)).remove();
      $scope.nCampoExtra--;
      $scope.atributosExtraNombre[nCampoExtra] = '';
      $scope.atributosExtraValor[nCampoExtra] = '';
    }
  };

先感谢您。


更新

根据@georgeawg 的建议,我使用 ng-repeat 动态创建了表单。目前它可以正常工作,只是不显示 md-autocomplete 的 ng-messages。接下来是 HTML 代码,它是一个模板,因为表单显示在一个对话框中。

'<md-dialog aria-label="List dialog" >' +
    '<md-toolbar>' +
    '          <div class="md-toolbar-tools">' +
    '            <h2>Atributos extra</h2>' +
    '            <span flex></span>' +
    '            <md-button class="md-icon-button" ng-click="closeDialog(false)">' +
    '              <md-icon md-svg-src="img/icons/ic_close_24px.svg" aria-label="Close dialog"></md-icon>' +
    '            </md-button>' +
    '          </div>' +
    '</md-toolbar>' +
    '<md-dialog-content style="max-width:80%; max-height:80%; min-width: 425px; min-height: 400px;" layout-align="center center">' +
    '<div class="md-dialog-content">'+
      '<form name="formAtributosExtra" ng-submit="actualizarAtributos()" >'+
        '<div layout="row">'+
          '<md-button class="md-fab md-mini" aria-label="Añadir campo" ng-click="crearCampo()" >'+
            '<md-icon md-svg-src="img/icons/add.svg"></md-icon>'+
          '</md-button>'+
          '<md-button class="md-fab md-mini" aria-label="Quitar campo" ng-click="quitarCampo()" >'+
            '<md-icon md-svg-src="img/icons/remove.svg"></md-icon>'+
          '</md-button>'+
        '</div>'+
        '<div ng-repeat="atributo in numeroAtributos" style="max-height: 95px;">'+
          '<md-input-container flex="50">' +
            '<md-autocomplete required="required" md-no-cache="noCache" md-input-name="atributoExtraNombre{{$index}}" md-input-id="searchinput{{$index}}" md-selected-item="selectedItem[$index]" md-search-text-change="searchTextChange(searchText[$index])" md-search-text="searchText[$index]" md-selected-item-change="selectedItemChange(item)" md-items="item in querySearch(searchText[$index])" md-item-text="item.display" md-min-length="0" md-floating-label="Atributo extra {{$index + 1 }}">'+
            '<md-item-template style="color: #9ea1a4;">'+
              '<span md-highlight-text="searchText[$index]" md-highlight-flags="^i">{{item.display}}</span>'+
            '</md-item-template>'+
            '<md-not-found ng-hide="extraCreado">'+
            '<md-button ng-hide="extraCreado" ng-click="crearCampoExtra(searchText[$index], $index)" style="width: 100%; text-align: center;">Crear!</md-button></md-not-found>'+
            '<div ng-messages="formAtributosExtra[\'atributoExtraNombre\' + $index].$error">'+
              '<div ng-message="required">Required</div>'+
            '</div>'+
            '</md-autocomplete>'+
          '</md-input-container>'+
          '<md-input-container flex="50">'+
            '<label>Valor atributo extra {{$index + 1}}</label>'+
            '<input name="atributosExtraValor{{$index}}" ng-model="atributosExtraValor[$index]" required>'+
            '<div ng-messages="formAtributosExtra[\'atributosExtraValor\'+$index].$error" ng-show="formAtributosExtra[\'atributosExtraValor\'+$index].$touched">'+
             '<div ng-message="required">Campo requerido</div>'+
            '</div>'+
          '</md-input-container>'+
        '</div>'+
      '</form>'+
    '</div>'+
  '  </md-dialog-content>' +
  '  <md-dialog-actions>' +
  '    <md-button ng-click="closeDialog(false)" class="md-primary">' +
  '      Cerrar' +
  '    </md-button>' +
  '<md-button type="submit" class="md-raised md-primary" ng-disabled="formAtributosExtra.$invalid" ng-click="actualizarAtributos()" class="md-primary">' +
  '      Guardar' +
  '    </md-button>' +
  '  </md-dialog-actions>' +
  '</md-dialog>',

标签: javascriptangularjsvalidationangularjs-materialangularjs-ng-form

解决方案


推荐阅读