Frage AngularJS mehrstufige Formularvalidierung mit dem UI-Router-Modul


Ich habe ein Formular, das über mehrere Tabs verteilt ist. Ursprünglich habe ich die Tabset-Direktive von ui-bootstrap verwendet, aber dann kam die Anforderung, eine Deep-Link zu einer bestimmten Registerkarte, also dachte ich, ich würde verschachtelte Ansichten von Ui-Router verwenden.

Das Problem, das ich habe, ist, dass das übergeordnete Formular nur gültig ist, wenn alle Unterformulare gültig sind, aber unter Verwendung von UI-Router-Status wird jeweils nur ein Unterformular geladen.

Hier ist ein Beispiel zur Klärung

index.html

<!DOCTYPE html>
<html ng-app="app">
<head>
  <script src="//code.angularjs.org/1.3.0-beta.5/angular.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <script src="script.js"></script>
</head>
<body class="container-fluid">
  <div ui-view>
    <ul class="list-unstyled">
      <li><a ui-sref="edit.basic">Basic</a></li>
      <li><a ui-sref="edit.extended">Extended</a></li>
    </ul>
  </div>
</body>
</html>

script.js

angular.module('app', ['ui.router']).
config(function($stateProvider) {
  $stateProvider.state('edit', {
    abstract: true,
    url: '/edit/',
    templateUrl: 'edit.html',
    controller: function($scope) {
      $scope.model = {};
    }
  }).
  state('edit.basic', {
    url: '/basic',
    templateUrl: 'basic.html'
  }).
  state('edit.extended', {
    url: '/extended',
    templateUrl: 'extended.html'
  });
});

edit.html

<div class="row" ng-form="editForm">
  <div class="col-xs-12">
    <ul class="nav nav-tabs">
      <li ui-sref-active="active">
        <a ui-sref="edit.basic">Basic</a>
      </li>
      <li ui-sref-active="active">
        <a ui-sref="edit.extended">Extended</a>
      </li>
    </ul>
  </div>
  <div class="col-xs-12" ui-view></div>
  <div class="col-xs-12">
    <button type="button" class="btn btn-primary" ng-disabled="editForm.$invalid">Save</button>
  </div>
  <div class="col-xs-12">
    <hr>
    <tt>model = {{model}}</tt><br>
    <tt>editForm.$valid = {{editForm.$valid}}</tt><br>
    <tt>editForm.basicForm.$valid = {{editForm.basicForm.$valid}}</tt><br>
    <tt>editForm.extendedForm.$valid = {{editForm.extendedForm.$valid}}</tt>
  </div>
</div>

basic.html

<div ng-form="basicForm">
  <div class="form-group">
    <label for="textProperty">Text Property</label>
    <input type="text" class="form-control" name="textProperty" id="textProperty" ng-model="model.textProperty" required>
  </div>
</div>

erweiterte.html

<div ng-form="extendedForm">
  <div class="form-group">
    <label for="numericProperty">Numeric Property</label>
    <input type="number" class="form-control" name="numericProperty" id="numericProperty" ng-model="model.numericProperty" required>
  </div>
  <div class="form-group">
    <label for="dateProperty">Date Property</label>
    <input type="date" class="form-control" name="dateProperty" id="dateProperty" ng-model="model.dateProperty" required>
  </div>
</div>

Ich fange an zu glauben, dass dieser Ansatz für meinen Zweck nicht geeignet ist. Anstatt verschachtelte Ansichten zu verwenden, sollte ich weiterhin den Tabset verwenden und einen Zustandsparameter verwenden, um die entsprechende Registerkarte zu aktivieren.

Ich bin interessiert zu wissen, wie andere es lösen würden.

UPDATE 1:

Hier ist eine Lösung, die ich gefunden habe, die das UI-Bootstrap-Tabset verwendet, aber nicht verschachtelte UI-Router-Zustände verwendet und stattdessen die aktive Registerkarte parametrisiert.

UPDATE 2:

Hier ist eine Lösung, die verschachtelte Zustände zusammen mit einem Validator-Dienst verwendet, der dem Vorschlag von Santiago Rebella folgt

UPDATE 3:

Hier ist eine alternative Lösung zu Update 2, die ein Validator-Objekt im Bereich des übergeordneten Status zum Vergleich verwendet


10
2017-08-26 16:06


Ursprung


Antworten:


Du könntest versuchen, es so zu machen, wie du sagst, dass du nur einige Attribute wie Schritt1, Schritt2 usw. an einen Dienst übergibst und true hinzufügst oder was auch immer dein Erfolgswert sein mag, also sobald alle diese Attribute wahr sind, in deinem ng -disabled oder die Art und Weise, wie Sie Ihr Formular erstellen, darf eingereicht werden.

Vielleicht könnten Sie bei früheren Formschritten die Werte der Eingaben in einem Objekt in Ihrem Service speichern. Ich denke auf diese Weise könnte man eine mehrseitige Form haben.


5
2017-08-26 16:13



controller.js

var app = angular.module('employeeDemoApp');
app.controller('employeesCtrl', function($scope, $state, EmployeeService, $stateParams) {
    console.log("Hello")
        $scope.saveEmployee = function(formname){
            console.log(formname.$error)
            EmployeeService.saveEmployee($scope.user);
            $state.go("employees");
        }
        $scope.employeeslist = EmployeeService.getEmployees();
        if($stateParams && $stateParams.id){
            $scope.user = EmployeeService.getEmployee($stateParams.id);
            $scope.user.dob = new Date($scope.user.dob);
            console.log("gdfg", $scope.user)
        }
        $scope.updateEmployee = function(req){
          EmployeeService.updateEmployee($stateParams.id, $scope.user);
          $state.go("employees")
        }
        $scope.goto_new_employee_page = function(){
        $state.go("employees_new")
    }
        $scope.deleteEmployee = function(index){
            console.log("fgdfhdh")
            EmployeeService.deleteEmployee(index);
             $scope.employeeslist = EmployeeService.getEmployees();
        } 
});

0
2018-02-15 05:30