Zum Inhalt springen
  • 0

JS/Angular: Formular-Template mit verschiedenen Datentypen generieren


Saheeda

Frage

Hallo,

ich soll eine Ansicht entwickeln, auf welcher man die Daten von zwei Entities "mergen" kann. Die Oberfläche sieht momentan ungefähr so aus, wie im Anhang (Wenn jemand ne bessere Idee hat, nehme ich gern!).

Ich habe so ungefähr 25 verschiedene Felder und bin nicht so scharf drauf, das alles per Hand zu schreiben und zu pflegen. Grade Änderungen am Styling (z.B. neue HTML-Klassen) sind so relativ mühsam.

Der simpelste Ansatz ist dieser:

<tr ng-repeat = "(prop, value) in update"> 
  <td><label>{{prop}}</label></td>
                <td><input type="text" ng-model="update[prop]"/>
                  <label>{{backup[prop]}}</label>
  </td>
  <td><input type="button" value="<" ng-click="copyToLeft(prop)" /</td>
  <td><label>{{toDelete.prop}}</label></td>
</tr>

 

"Update" ist die Entity, die momentan bearbeitet wird und in welche die Daten "hineingemerged" werden. Backup ist eine Kopie davon, die links neben den Buttons eingeblendet wird, damit der Benutzer abgleichen kann, wie es vorher war. Rechts neben den Buttons is "toDelete", da dieser Datensatz nach dem Mergen gelöscht wird. Problem: Bei booleans wird "true" angezeigt, bei Arrays "[]", was zwar korrekt, aber so für einen Laien nicht benutzbar ist. Es gibt insgesamt 3 Arten von Datentypen in den Feldern: Strings, Booleans und Arrays von Objekte. Wobei die Objekte alle nur die beiden Felder id und title haben.

Soviel zu den Anforderungen. Ich habe einen Code, der macht, was er soll. Aber naja... es ist verdammt hässlich und hat einige Wiederholungen und potentielle Fehlerquellen: Hat jemand nen Tipp für mich, wie ich das Template schöner generieren kann? Ich habe hier auch schon mit ng-switch experimentiert, aber das funktioniert leider nicht bei Ausdrücken wie isBoolean(), sondern nur bei hart codierten Bedingungen.

<body ng-controller="mergeController">
        <table>    
            <tr ng-repeat = "(prop, value) in update">
                <td><label>{{prop}}</label></td>
                <td>      
                    <div ng-if="isBoolean(value)"> 
                        <input type="checkbox" ng-model = "update[prop]">                                                                  
                    </div>                    

                    <div ng-if="isArray(value)" ng-repeat="item in value track by $index">
                        <input ng-model="update[prop][$index].title"/>                        
                    </div>

                    <div ng-if="!isBoolean(value) && !isArray(value)">                        
                        <input type="text" ng-model="update[prop]"/>                        
                    </div>
                </td>
                <td>
                     <div ng-if="isBoolean(value)">                         
                        <input type="checkbox" ng-model = "backup[prop]" ng-disabled="true">                        
                    </div>                    

                    <div ng-if="isArray(value)" ng-repeat="item in value track by $index">                        
                        <label>{{backup[prop][$index].title}}</label>
                    </div>

                    <div ng-if="!isBoolean(value) && !isArray(value)">                                                
                        <label>{{backup[prop]}}</label>
                    </div>
                </td>                
                <td>
                    <div ng-if="isArray(value)" ng-repeat = "(key, item) in value track by $index">                    
                        <input  type="button" value="<" ng-click="copyToLeftInArray(prop, $index)" />
                    </div>
                    <div ng-if="!isArray(value)">
                        <input type="button" value="<" ng-click="copyToLeft(prop)" />
                    </div>
                </td>              
                <td>
                    <div ng-if="isBoolean(value)">
                        <input type="checkbox" ng-model="toDelete[prop]" ng-disabled = "true"/>
                    </div>
                    <div ng-if="isArray(value)" ng-repeat = "item in value track by $index">                        
                        <label>{{toDelete[prop][$index].title}}</label>                        
                    </div>
                    <label ng-if="!isArray(value) && !isBoolean(value)">{{toDelete[prop]}}</label>
                </td>
            </tr>
        </table>

        <input id="submit" type="button" value="Merge" ng-click="merge()">
    </body>

 

 

 

Controller:

app.controller("mergeController", [
        '$scope',
        function ($scope) {
            $scope.test = true;            
            
            $scope.update = {
                name: 'my name',
                online: true,
                friends: [
                    {
                        id: 1,
                        title: 'A'
                    },
                    {
                        id: 2,
                        title: 'B'
                    },
                    {
                        id: 3,
                        title: 'C'
                    }
                ]
            }            

            $scope.backup = {};            
            for (var prop in $scope.update) {
                if ($scope.update.hasOwnProperty(prop)) {
                    $scope.backup[prop] = $scope.update[prop];
                }
            }            
            $scope.toDelete = {
                name: 'other',
                online: false,
                friends: [
                    {
                        id: 4,
                        title: 'D'
                    },
                    {
                        id: 5,
                        title: 'E'
                    },
                    {
                        id: 6,
                        title: 'F'
                    }
                ]
            }   
            
            $scope.copyToLeft = function (attribute) {                
                $scope.update[attribute] = $scope.toDelete[attribute];               
            }            
            
            $scope.copyToLeftInArray = function (attribute, index) {                
                $scope.update[attribute][index] = $scope.toDelete[attribute][index];                
            }            

            $scope.isBoolean = function (value) {         
                return typeof(value) === 'boolean';
            }

            $scope.isArray = function (value) {
                return Array.isArray(value);
            }
        }
    ]);

 

merge.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Empfohlene Beiträge

  • 0

Hallo @Saheeda

leider sind mir die Anforderungen noch nicht ganz klar... kann man beim mergen Teile eines Arrays in dem anderen hinzugefügt werden? scheint so zumindest auf dem Bild.

ich persönlich wurde so wenig Logik wie möglich in den HTML einbauen, bei dir sieht es wie ein richtigen Script. Schöner wäre es, wenn in <dt>{{zeigeWert(property, object)}}</dt> nur eine Funktion aufgerufen wird und die Auswertung in den Controller implementiert ist. Vorteile: Sieht sauberer aus, kann man Fehler schneller finden und du kannst auch Tests einbauen, um zum Beispiel die if-elses zu testen.

Am 6.12.2015 um 19:39 schrieb Saheeda:

Problem: Bei booleans wird "true" angezeigt, bei Arrays "[]",

 Ich verstehe nicht ganz auf was das bezogen wird.

Die Backup Initialisierung kannst du in deinem Fall auf eine Zeile verkürzen: $scope.backup = angular.copy($scope.update); // ist eine art Klon total losgelöst von Referenzierungen.

Nichtdestotrotz wurde ich den Ansatz ändern und "update" erst überschreiben wenn man auf "Merge" klickt.

Ich habe das in JSFiddle durchgespielt: https://jsfiddle.net/eddiriarte/aszL78qn/ , man könnte tiefer gehen mehr kapseln und Factories(fürs Diff Object) verwenden usw. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...