Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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

  • 1 Monat später...

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. 

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.