SPA Formulare mit Angular.js

Das Formular ist nach wie vor der Standard-Anwendungsfall jeder Geschäftsanwendung. Dank der wirklich intelligenten Binding Engine von Angular und den dynamischen Eigenschaften von JavaScript geht das auch mit minimalem Programmieraufwand von der Hand.

Dem MVx Entwurfsmuster folgend, werden die Daten über einen Controller (à la ViewModel) der HTML5-Sicht zu Verfügung gestellt. Ein Controller ist ein Stück JavaScript Code, das in der Regel in einer eigenen Datei ausgelagert wird. In diesem Fall befindet sich der Code innerhalb des HTML Dokuments. Wenn es sich um wenige Code-Zeilen handelt, könnte das sogar die bessere bzw. schnellere Option sein.

Startpunkt einer SPA ist das Modul, das einen oder mehrere Controller enthält.  Der Controller verweist auf die (in diesem Fall willkürlich) ident benannte Methode. Diese ist sozusagen der Constructor, wird also einmalig und automatisch aufgerufen, wenn der Controller im HTML referenziert wird. Wie in JavaScript typisch, wird einem Objekt, das hier $Scope genannt wird, dem DataContext entspricht, eine Eigenschaft und ein Methodenzeiger saveMe zugewiesen.

   1:     <script src="Scripts/angular.js"></script>
   2:      <script>
   3:          angular
   4:          .module('App', [])
   5:          .controller('myController', myController);
   6:          function myController($scope)
   7:          {
   8:              $scope.person = {};
   9:              $scope.saveMe=function(person)
  10:              {
  11:  alert(person.name);
  12:              };
  13:          }
  14:      </script>
  15:  </body>

 

Die HTML Seite beginnt mit dem ng-app Attribut und dem ng-Controller, der auf den Controller-Namen verweist.

Binding wird ähnlich zu XAML mit {} deklariert, nur eben in doppelter Form. Da JavaScript-Objekte nicht streng typisiert sind, kann man nun einfach ein fiktives Objekt, hier einfach person genannt, verwenden. Das ist für den Objektorientierten oder Prozeduralen Entwickler kaum zu akzeptieren. Dem fiktiven Element kann man auch Eigenschaften andichten. Aus fiktiv wird in Zeile 4 aber Ernst. Diese Zeile dient nur zur Demonstration der Binding-Funktion. Diese wird adhoc aktualisiert, wenn sich der Wert ändert.

In dem Eingabefeld wird die Bindung per ng-model an das idente (Achtung: case-sensitiv) person-Objekt vorgenommen. Sobald der Benutzer etwas tippt, wird auch die Anzeige im Div refreshed.

   1:  <body ng-app="App">
   2:      <div ng-controller="myController">
   3:          <form name="form1" novalidate>
   4:              <div>{{person.id}} -{{person.name}} -
{{form1.$invalid}}</div>
   5:              <input required ng-model="person.id" /><br />
   6:              <input required ng-model="person.name" 
ng-minlength="2" /><br />
   7:              <button ng-click="saveMe(person)"
   8:                      ng-disabled="form1.$invalid">
   9:                  Speichern
  10:              </button>
  11:          </form>
  12:    </div>

Die Eingaben müssen überprüft werden, bevor die Daten über einen REST Calll an den Server geschickt werden. Für diesen Form Validation Prozess gibt es leider viel zu viele Möglichkeiten. HTML Form Input Validation, hier mit dem Attribut required. Diverse JQuery Plugins und auch Angular hat Validierungsattribute. ng-minlength ist eine Direktive, die darüber wacht, dass die Aktualisierung des Models Person erst erfolgt, wenn sie mindestens zwei Zeichen lang ist.

Allerdings passiert das völlig im Hintergrund. Die Visualisierung der Regeln und das Feedback zum Benutzer muss selbst erstellt werden. Über eine Bindung zum Form und der $invalid-Eigenschaft, kann man z. B.  den Submit-Button deaktivieren. Aus UX-Sicht ist das jedoch keine gute Praxis, da der Grund nicht leicht erkennbar ist.

Drückt der Benutzer auf Speichern, wird das person-Objekt als Parameter in der Save-Methode übergeben. Diese wird ebenfalls per Angular Directive erstellt.

Dies und noch einiges mehr wird Thema des Single Page Application Workshops mit Angular und ASP.NET sein, den ich auf der #ADCX halten werde.

Kommentare sind geschlossen