AngularJS geht auch übersichtlich

15. August 2019 Andreas Peters

In JavaScript zu programmieren hat einen ziemlich schlechten Ruf. Der Code ist unübersichtlich, schlecht Strukturiert, die Frameworks sind zu gross und teils schlecht umgesetz, häufig viel zu kompliziert und zu guter letzt gibt es noch eine (so scheint es) unendlich grosse Anzahl. Aber es gibt auch ausnahmen. So haben wir bis vor wenigen Jahren mit enyoJs Frontends aufgebaut. EnyoJS hat alles was sich ein Strukturierter Programmierer wünscht. Der Code ist aufgeräumt, in Klassen unterteilt, GUI Elemente sind getrennt einzugeben und deren hinterlegte Aktionen sind einfach und sauber einzubinden. Leider wird enyoJS nicht mehr weiter entwickelt. Auf welches Framework also nun setzen? Nun, eines sei vorab gesagt, keines der von uns angeschauten Javascript Frameworks (ausser das deprecated enyoJS) genügt unseren Ansprüchen. Code muss sauber und übersichtlich sein, damit der Kunde die Möglichkeit hat, schnell und einfach weitere Features hinzuzufügen oder schon vorhandenen abzuändern. Zumindest ist das unsere Massgabe.

Nach langen suchen und probieren haben wir wieder ein etwas betagtes aber nach wie vor gepflegtes Framework gefunden. AngularJS! Dies ist zwar per default so unübersichtlich wie alle anderen auch, aber es gibt einen die Freiheit eigene Strukturen einzubringen. Dies möchten wir hier einmal darstellen.

AngularJS trent die GUI Elemente von dem Code. Die GUI Elemente legen wir in Dateien ab die jeweils der GUI nach in dem Format GUI.view.html benannt wurde. Der Code liegt dabei in GUI.controller.js

GUI.controller.js

Hier ein Beispiel vom aufbei eines Controllers:

(function () {
    'use strict';

Wir geben diesem Controller einen Unique Namen um die Funktionen im Controller mit der entsprechenden GUI verknüpfen zu können.

    angular
        .module('app')
        .controller('UserController', UserController);

Dem Controller übergeben wir Globale Variablen aus geladenen Libs oder eigenen Services (diese werden später erklärt).

    UserController.$inject = ['$rootScope', 'UserService', '$location', '$window', 'Service'];

Ab hier beginnen wir mit den im Controller bereitzustellenden Funktionen.

    function UserController($rootScope, UserService, $location, $window, Service) {
        var vm = this;

        vm.root = $rootScope;
        vm.data = [];
        vm.open = open;

        loadData($location.search().id);

        function initController() {
            if ($rootScope.globals.currentUser !== undefined) {
                $rootScope.checkToken();
                UserService.GetUserData().then(function (users) {
                    if (users) {
                        vm.loginUser = users;
                    }
                });
            }
        }

        function open(id) {
            $window.open('/#!/public/view?id='+id, '_blank');
        }

        function loadData(id) {
            Service.GetData(id).then(function (res) {
                vm.data = res;
            });
        }
    }
})();

GUI.view.html

In der GUI können wir nun den obigen Controller Referenzieren.

<div layout="column" ng-controller="UserController">
    <md-button ng-mouseenter="$vm.open()">
    </md-button>
</div>

Der Service

Kommen wir nun zu dem Service der vom Controller aus aufgerufen wird und global definiert wurde. Der hier im Beispiel gezeigte UserServer ruft lediglich eine externe API auf um dort irgendwelche Daten abzurufen. Es dient hier als Beispiel, wie man in AngularJS nachträglich Daten lädt und verarbeitet.

(function () {
    'use strict';

    angular
        .module('app')
        .factory('UserService', UserService);

    UserService.$inject = ['$http', '$rootScope'];
    function UserService($http, $rootScope) {
        var service = {};

        service.GetData = GetData;

        return service;

        function GetData() {
            setHeader();
            return $http.get($rootScope.env.USER_API_SERVER+'/api/user/v0').then(handleSuccess, handleError('Error get user data'));
        }

        function setHeader() {
            if (!$rootScope.globals.currentUser) {
                return;
            }
           $http.defaults.headers.common['Authorization'] = 'Bearer ' + $rootScope.globals.currentUser.token;
        }

        function handleSuccess(res) {
            return res.data;
        }

        function handleError(error) {
            return function () {
                return { success: false, message: error };
            };
        }
    }

})();