Archiv der Kategorie: AngularJS

Kommerzielle Ui Framworks für Angular 1 / 2 (Telerik, DevExpress, …)


Es gibt zwar eine Menge kostenlose Ui Frameworks für AngularJs, diese beinhalten aber meist nur die Standardkomponenten und z.B. kein richtiges Data Grid. Da ich aber ein richtiges Data Grid benötigte, musste ich mich also nach kommerziellen Lösungen umsehen. Bei den kommerziellen Lösungen habe ich leider keines finden können welches Nativ in AngularJs 1.x geschrieben ist. Außer Ionic, aber dabei handelt es sich um ein pures Mobile Framework. Für die Standardwebanwendungen gibt nur Lösungen die im Kern auf jQuery setzen und dann nach außen hin einen Angular “Wrapper” / Schnittstelle anbieten, so dass man denkt man verwendet native Angular Komponenten. Dafür gibt es inzwischen bei allen Anbietern TypeScript Support, mit Hilfe von passenden Typings für das jeweilige Framework, ist IntelliSense dann auch kein Problem mehr.

Am Ende habe ich nur vier Anbieter finden können, die mir zugesagt haben, die zumindest laut Webseite eine Angular 1 Integration bieten. Dabei handelte es sich um

1. DevExpress mit DevExtreme

Wie schon anfangs erwähnt handelt es sich bei der Angular 1.x Umsetzung um einen Wrapper mit dem alle DevExtreme Controls auch für Angular bereitstehen. Bei DevExtreme handelt es sich um die günstigste Lösung, wenn man nur auf JavaScript Webkomponenten angewiesen ist. Die Dokumentation ist spitze und enthält live Beispiele die man direkt anpassen und ausprobieren kann. Außerdem gibt es einen Themebuilder in dem ich meine Bootstrap 3 Variablen einlesen kann und DevExtreme dann entsprechend meine gewohnten Styles verwendet für Bootstrap 3. Außerdem scheint es ein recht aktives Forum zu geben in dem DevExpress Mitarbeiter zu vielen Fragen die passenden Antworten liefern.

Da die Grundvoraussetzungen sehr gut waren, habe ich hier auch die Trial Version ausprobiert und meine erste simple Angular 1.x Anwendung mit einer DevExtreme Textbox die an das ngModel gebunden wurde, hat auch nicht länger wie 20 Minuten gedauert (sehr gute Dokumentation). Leider musste ich bereits hier feststellen, das die Implementierung nicht Angular Like umgesetzt wurde. Denn die Eingabe in das Textfeld wurde erst dann in meine lokale Angular Variable zurückgeschrieben wenn ich das Textfeld verlassen habe (also kein “natives” TwoWayModel Binding out of the box). Außerdem konnte ich für die Validierung nicht wie gewohnt über AngularJs gehen und die Form Variablen wie $valid … verwenden, sondern hier muss ein eigener Validator von DevExtreme verwendet werden, was das Zusammenspiel von eigenen Angular Komponenten und DevExtreme quasi “unmöglich” macht. Wenn man also ein Formular mit Validierung bauen möchte, verwendet man am Besten nur DevExtreme Komponenten.

Dann habe ich noch die Autocomplete Textbox ausprobiert und versucht eine Serverseitige Abfrage für die Autocomplete Elemente zu implementieren, was mir nach 4 Stunden nur zum Teil gelungen ist und ich mit der Implementierung nicht wirklich zufrieden war.

Für DevExtreme gibt es aktuell eine Angular 2 Implementierung im CTP Status – zum ausprobieren. Dabei handelt es sich aber ebenfalls um einen Wrapper der wieder auf jQuery zurückgreift. Hier hat man dann aber anscheinend wieder alle gewohnten DevExtreme Funktionen auch in Angular 2 Anwendungen zur Verfügung.

2. Infragistics mit Ignite UI

Hier wird zwar auf der Webseite mit AngularJs geworben, aber es wird nur auf ein GitHub Repository verwiesen, was nur einen Bruchteil der Controls enthält die für das normale Ignite UI mit jQuery zur Verfügung stehen. Außerdem ist die Dokumentation mehr als nur fragwürdig, zumindest für die Angular Implementierung. Auch die angebotene Angular 2 Implementierung hat zumindest Abhängigkeiten auf jQuery und dies hört sich im ersten Moment nicht nach einer nativen Implementierung an.

Aufgrund der “schlechten” Grundvoraussetzungen habe ich hier auch keine Trial Version ausprobiert. Denn das Produkt kam schon aufgrund der schlechten Dokumentation und wenigen Controls für Angular nicht mehr in die nähere Auswahl.

3. Syncfunctions

Auch hier handelt es sich um eine recht große Anzahl an Controls die einem zur Verfügung stehen und für die es einen Angular 1.x und Angular 2 Wrapper gibt. Leider war auch hier die Dokumentation für die AngularJs Integration bzw. jQuery so schlecht, das es keine Live Beispiele gab, sondern nur Code Snippets mit passenden Screenshots dazu. Aufgrund der schlechten Dokumentation habe ich auch hier keine Testversion ausprobiert.

4. Telerik mit Kendo UI

Auch Telerik bietet für die Angular 1 Integration nur einen Wrapper an, dieser ist aber meiner Meinung nach wesentlich besser wie der von DevExtreme. Denn hier bin ich nicht komplett auf die Controls von Kendo UI angewiesen, sondern kann auch problemlos meine eigenen Controls verwenden wenn ich z.B. ein Formular mit Validierung erstellen möchte. Denn die Controls von Kendo UI integrieren sich “fast” nahtlos in die Angular Welt. Wichtig ist hier die passenden Dokumentationsschritte für AngularJS zu lesen, dann versteht man auch die normale Dokumentation etwas besser, wenn man hier teilweise nicht direkt etwas von AngularJs liest. Außerdem ist die Dokumentation sehr gut, es gibt Live Beispiele die man auch direkt bearbeiten kann und sieht was sich ändert. Auch Kendo UI stellt einen Themebuilder zur Verfügung, der zumindest einen rudimentären Support für Bootstrap bereitstellt. Leider wird bei den Icons noch auf das Sprite Image mit Icons von Bootstrap 2 gesetzt. Damit ist der Themebuilder leider nicht so gut wie der von DevExtreme, wenn es um die Bootstrap Integration geht.

Da aber auch hier die Grundvoraussetzungen gepasst haben, habe ich die Testversion ausprobiert und hatte bereits nach 20 Minuten meine erste AngularJs Anwendung mit einem DatePicker erstellt. Außerdem war es mir möglich innerhalb von 3 Stunden eine Autocomplete Textbox mit Serverseitiger Abfrage zu erstellen ohne größere Probleme, was mir in DevExtreme nicht gelungen ist.

Auch Kendo UI stellt eine Angular 2 Implementierung seiner Controls zur Verfügung, diese werden aber gerade komplett neu nativ in Angular 2 erstellt und daher gibt es auch erst eine Beta mit nur ein paar Controls. Es gibt aber eine gut einsehbare Timeline und Kommunikation in der gesagt wird wie der aktuelle Releaseplan aussieht.

5. Fazit

Prinzipiell blieben nur zwei Frameworks übrig zwischen denen ich mich entscheiden musste, denn nur bei DevExtreme und Kendo UI waren wirklich sehr gute Dokumentationen vorhanden. Denn die Dokumentation muss bei der puren Anzahl an Einstellungsmöglichkeiten, die für die einzelnen Controls zur Verfügung stehen einfach sehr gut ausfallen, sonst ist man nur auf den Support des Anbieters angewiesen. Da ich aber auch weiterhin eigene AngularJs Controls verwenden wollte, war mir eine möglichst native AngularJs Integration auch sehr wichtig und daher verwende ich aktuell Kendo UI.

Mit der aktuellen Kendo UI Version, habe ich bisher das Grid und das Gantt Chart verwendet und hier merkt man teilweise schon sehr das hier eine jQuery Implementierung vorliegt und keine native AngularJs Implementierung. Trotzdem bin ich mit dem was das Grid bzw. das Gantt Chart kann sehr zufrieden und es gliedert sich soweit auch ganz gut in meine AngularJs Anwendung ein. Außerdem ist der Support bisher auch ganz gut, dieser antwortete in der Regel innerhalb von 2 Tagen, bisher auf jedes Problem was ich hatte und keinen passenden Forumseintrag finden konnte. Bei der Verwendung von “einfachen” Controls wie der Datepicker, denkt man schon “fast” das man eine reine AngularJs Implementierung vorliegen hat. Außerdem bin ich auf die nativen Angular 2 Implementierungen vom Kendo UI gespannt.

HINWEIS: Wer sich für ein kommerzielles UI Framework für AngularJs interessiert, dem würde ich meiner Meinung nach auf jeden fall empfehlen das er DevExtreme und Kendo UI einmal selbst ausprobiert und prüft womit man selbst am besten klar kommt.

Außerdem möchte ich darauf hinweisen, das ich beide Frameworks vorher noch nicht verwendet habe und mir durchaus auch ein Fehler bei der Verwendung von DevExtreme unterlaufen sein kann, warum ich z.B. die Autocomplete Textbox nicht mit meinen Ansprüchen zum Laufen bekommen habe oder das TwoWay Databinding nicht so funktionierte wie von mir erwartet.

AngularJs TypeScript Interceptor Template


AngularJs bietet ein interessantes Konzept um AJAX Requests bzw. Response zu manipulieren oder zu prüfen ob ein Response bestimmte Daten enthält. Das ganze nennt sich HTTP Interceptor. Ich verwende es z.B. für die folgenden Aufgaben in meinen Projekten

  • Prüfen ob im Response eine Meldung enthalten ist die angezeigt werden soll, wenn diese vorhanden ist, existiert im Response JSON immer ein Property mit dem Namen “Message” und dieses wird dann entsprechend ausgewertet und angezeigt ohne das ich an der eigentlichen Funktion wo der Request gestartet wurde in irgendeiner Art eingreifen muss.
  • Prüfen ob der Response fehlerhaft ist und wenn ja auf eine Fehlerseite umleiten und den Fehler entsprechend anzeigen.
  • Bei einem Request den Header manipulieren und noch ein Antiforgery Token hinzufügen
  • Bei einem Request prüfen ob es sich um den IE handelt und hier das Caching für AJAX Requests über die Standard Header deaktivieren

Dies sind nur einige wenige Funktionen wo es sich lohnt auf AngularJS HTTP Interceptoren zu setzen.

Ein passenden Template für einen HTTP Interceptor in TypeScript sieht z.B. folgendermaßen aus.

 

Ein Beispiel wie das ganze in einem Projekt eingebunden werden kann findet Ihr in meinem GitHub Projekt.

T4 Template als Service/Proxybuilder für AngularJs TypeScript Services


Wenn man einen AngularJs HTTP Service erstellt der die Verbindung zum .NET Controller herstellen soll um Daten abzufragen oder zu speichern, handelt es sich immer um den “gleichen” boilerplate Code der geschrieben werden muss. Genau hier setzt mein T4 Template der Proxybuilder an und generiert die passenden AngularJs Services in JavaScript oder auch in TypeScript und in Verbindung mit TypeLite werden komplett typisierte Services erstellt.

Damit das ganze funktioniert muss man nur noch seine Controller Methoden mit einem passenden Attribut versehen z.B. “CreateAngularTsProxyAttribute”. Dann das Projekt kompilieren und das T4 Template “Scripts\ProxyGeneratorScript.tt” ausführen und schon werden die passenden AngularJs Service Funktionen erstellt. Aus dem folgenden .NET Controller

wird dann der volltypisierte AngularJs TypeScript Controller der vom T4 Template generiert wurde.

Das komplette Projekt findet Ihr auf GitHub inklusive einer ausführlichen Beschreibung und ein Beispielprojekt. Das fertige Paket gibt es auch bei NuGet.

Der Proxybuilder kann die folgenden Proxies erstellen, dafür wird jeweils nur das passende Proxybuilder Attribut benötigt:

  • AngularJs pure JavaScript Services
  • AngularJs TypeScript Services voll Typisiert und nur in Verbindung mit TypeLite zu verwenden. TypeLite erstellt Interfaces von unseren .NET Klassen in TypeScript, die der Proxybuilder dann verwendet für Übergabe- und Rückgabewerte.
  • jQuery pure JavaScript Services
  • jQuery TypeScript Services voll Typisiert und nur in Verbindung mit TypeLite.

Wenn Ihr Fragen oder Erweiterungswünsche habt, dann bitte auf GitHub als Issue eintragen.

Angular 1.5 Component Template in TypeScript


Seit Angular 1.5 gibt es noch eine neue Möglichkeit um Direktiven zu erstellen. Der neue Typ nennt sich “component” und bietet einige Vorteile gegenüber der klassischen Direktive. Dazu gehören z.B. die einfachere Konfiguration, da viele Werte bereits vorkonfiguriert sind mit den am häufigsten verwendeten Werten. Dann ist bereits die ControllerAs Syntax eingebaut, in dem man im Template standardmäßig direkt auf die Bindings (früher scope) über “$ctrl.varname” zugreifen kann. Außerdem gibt es so genannt LifeCycle Hooks wie man sie inzwischen aus Angular 2 kennt und welche erst zu einem bestimmten Zeitpunkt aufgerufen werden. Wie z.B. “$onInit()”, welche erst aufgerufen wird, wenn alle Controller und Ihre Bindungen erstellt wurden. Sie kann z.B. zur Initialisierung von eigenen Werten genutzt werden (Quelle, Angular Doku).

Im Folgenden ein einfaches TypeScript Template für die Erstellung einer Component für Angular 1.5. Wie ihr das ganze einbinden und verwenden könnt, findet Ihr auch in meinem GitHub Projekt.

AngularJs Draggable Direktive für UI-Bootstrap Modal in TypeScript


In meinen aktuellen AngularJs Projekten verwende ich für das Layout meist Bootstrap und für die JavaScript Umsetzung der Komponenten dann entsprechend UI-Bootstrap. Seit einiger Zeit wird das Projekt auch wieder aktiv weiterentwickelt. Leider werden die Komponenten sehr “einfach” gehalten und setzen nur die Funktionalität um die auch das klassische Bootstrap bietet. Es gibt noch weitere Komponentenanbieter für Bootstrap, wie z.B. AngularStrap wo mehr Zeit auch in zusätzliche Features investiert wurde, nur leider wird das Repo aktuell nicht mehr so regelmäßig aktualisiert.

Daher versuche ich aktuell vermehrt auf UI-Bootstrap zu setzen und habe hier eine einfache Direktive erstellt, mit der das Standard Modal Draggable wird. Dafür muss man einfach den Mauszeiger im Header des Modals gedrückt halten und man kann das Modal verschieben. Die Direktive muss dabei nur in AngularJs registriert werden, denn sie hängt sich automatisch an eine bestehende Modal CSS Klasse “modal-dialog” und damit sind alle Modals verschiebbar, wenn die Direktive einmal registriert wurde.

Der passende TypeScript Code zum Draggable Modal

AngularJs mit TypeScript und Resharper Templates


Seit gut 9 Monaten arbeite ich mit TypeScript und AngularJs zusammen und habe mir für die wichtigsten AngularJs Komponenten passende TypeScript Klassen gebaut. In Verbindung mit Resharper lässt sich damit sehr schnell eine funktionierende AngularJs Anwendung mit TypeScript aufsetzen, denn ich habe mir für die wichtigsten AngularJs Komponenten fertige Templates in Resharper hinterlegt. Denn auch hier gibt es wieder X Möglichkeiten eine Anwendung in TypeScript und AngularJs zu schreiben.

Es war mir aber erst mit der Benutzung von TypeScript Klassen möglich auch durchweg eine gute IntelliSense zu erhalten. Da die Implementierung von AngularJs mit TypeScript Klassen aber alles andere als intuitiv ist, war ich froh als ich für jede AngularJs Komponente die passende Klassen Implementierung erstellt hatte, dies war mir vor allem durch die gute Unterstützung der StackOverflow Community möglich.

Meine AngularJs Anwendungen bauen dabei auf folgende Komponenten auf:

  • Twitter Bootstrap 3.x (Styles und Modal)
  • AngularJs 1.4.x
  • Ui-Router
  • Angular-Ui (Modal)
  • AngularStrap für weitere Bootstrap Komponenten wie z.B. Date und Timepicker
  • aktuelle TypeScript Version die von Resharper unterstützt wird.

Ein komplettes sehr einfaches Beispiel, in dem ich alle folgenden Komponenten verwende findet Ihr auch auf meinem GitHub [AngularJsTypeScriptTemplates] Account, das Projekt ist als Visual Studio Solution hinterlegt. Außerdem findet Ihr dort auch meine TypeScript Live Templates für Resharper, diese lassen sich sehr einfach mit Resharper importieren und an eure Bedürfnisse anpassen. Im Folgenden findet Ihr einfach ein Beispiel für die jeweiligen AngularJs Komponenten umgesetzt in TypeScript.

Ich bin natürlich immer gern für Verbesserungsvorschläge offen und freue mich über Kommentare sollte ich etwas “falsch” machen oder wenn ich etwas besser umsetzen kann. Außerdem kann ich nur jedem empfehlen, einmal TypeScript auszuprobieren, ich könnte/möchte inzwischen nicht mehr ohne TypeScript arbeiten wollen, denn IntelliSense und Typsicherheit auch auf Clientseite sind einfach unbezahlbar.

1. Definieren der MainApp als Einstiegspunkt für die Anwendung

In der MainApp werden alle wichtigen Module registriert und z.b. die Routenkonfiguration aufgerufen.

module App {
    export class MainApp {
        static createApp(angular: ng.IAngularStatic) {
            //Alle Module definieren die wir verwenden.
            angular.module("app.main", [
                //Fremdanbieter Module
                "ui.router",
                "ui.bootstrap",
                //Module die mit TypeScript geschrieben wurden einbinden
                App.Controller.TodoModalCtrl.module.name,
                App.Controller.TodoCtrl.module.name,
                App.Services.TodoService.module.name,
                App.Services.ModalService.module.name,
                App.Directives.CtrlAsDirectiveName.module.name,
                App.Directives.DirectiveName.module.name,
                App.Filter.AddPrefixFilter.module.name,
            ])
            .config([
                "$stateProvider", "$urlRouterProvider", "$locationProvider", ($stateProvider: ng.ui.IStateProvider, $urlRouterProvider: ng.ui.IUrlRouterProvider, $locationProvider: ng.ILocationProvider) => {
                    return new Config.RouteConfig($stateProvider, $urlRouterProvider, $locationProvider);
                }
            ]);
        }
    }
}

//Unsere Anwendung intial aufrufen/starten
App.MainApp.createApp(angular);

/*Window Interface erweitern, damit wir auch hier auf z.b. eigene Properties zugreifen können die wir z.B: in alten JS dateien definiert haben */
interface Window {
    siteRoot: string;
}

2. Festlegen der Routen für Ui-Router

module App.Config {
    /**
     * Enthält die Routenconfigutation für unsere Anwendung.
    */
    export class RouteConfig {
        constructor(private $stateProvider: ng.ui.IStateProvider, private $urlRouterProvider: ng.ui.IUrlRouterProvider, private $locationProvider: ng.ILocationProvider) {
            this.init();
        }

        private init(): void {
            //$urlRouterProvider.when('/Home', '/home/index');
            this.$urlRouterProvider.otherwise("Todo");
            //$locationProvider.html5Mode(true);

            //Definieren der Routen die in unserer App zur Verfügung stehen.
            this.$stateProvider
                .state("Todo", {
                    url: "/Todo",
                    templateUrl: "Todo/TodoList"
                })
                .state("Todo.Overview", {
                    url: "/Overview",
                    templateUrl: "Todo/TodoOverview"
                });
        }
    }
}

3. Einrichten eines Controllers

Alle AngularJs Module die man registrieren kann, enthalten einen Bereich “Module Definition”, hier wird der Name des Moduls und der Typ festgelegt und z.B. in der MainApp als Abhängigkeit hinzugefügt. Achtung es wird die “ControllerAs ” Syntax verwendet, bei dem hier gezeigten Beispiel für einen Controller. Achtung beim Inject aufpassen, denn die Reihenfolge im Inject musst der Reihenfolge im Konstruktor der Klassen entsprechen.

module App.Controller {
    //import My = Sq.Internal.ProjectName.Gui.Web.Models;

    //Alle Variablen für unseren Controller im Interface definieren
    export interface ITodoCtrl {
        //Locals
        //viewModel: My.;
        //Functions
        init(): void;
    }

    //Unsere CtrlName Klasse erstellen
    export class TodoCtrl implements ITodoCtrl {
        private locals: CtrlNameLocalsModel = new CtrlNameLocalsModel();
        static $inject: string[] = [
            App.Services.TodoService.module.name,
            App.Services.ModalService.module.name,
        ];

        constructor(private todoService: Services.ITodoService,
                    private modalService: Services.IModalService) {
            this.init();
        }

        /**
        * Initialisieren der wichtigsten lokalen Variablen
        */
        init(): void {
            this.locals.persons = this.todoService.getPersonList();
        }

        public editPerson(personId: number): void {
            this.modalService.editPerson(personId).then(() => {
               //Do Something nachdem das Modal geschlossen wurde.
            });
        }


        //#region Angular Module Definition
        private static _module: ng.IModule;
        /**
         * Stellt das aktuelle Angular Modul für den "CtrlName" bereit.
         */
        public static get module(): ng.IModule {
            if (this._module) {
                return this._module;
            }

            //Hier die abhängigen Module für diesen controller definieren, damit brauchen wir von außen nur den Controller einbinden
            //und müssen seine Abhängkeiten nicht wissen.
            this._module = angular.module('todoCtrl', []);
            this._module.controller('todoCtrl', TodoCtrl);
            return this._module;
        }
        //#endregion
    }

    class CtrlNameLocalsModel {
        persons: App.Person[] = [];
        name : string = "SquadWuschel";
    }
} 

4. Einrichten eines Services

Auch der AngularJs Service enthält wieder einen Bereich für Module Definitionen, mit dem man den Service entsprechend in der MainApp registrieren kann.

module App.Services {
    //import My = Internal.;

    export interface ITodoService {
        getPersonList(): App.Person[];
        getPerson(personId: number): Person;
    }

    /**
     * Beschreibung
     */
    export class TodoService implements ITodoService {
        private persons : App.Person[] = [];

        static $inject: string[] = [];

        constructor() {
            this.persons.push(new App.Person("SquadWuschel", 34, 1337));
            this.persons.push(new App.Person("Squadinator", 33, 7331));
            this.persons.push(new App.Person("SquadLeader", 3232312123.4454545, 3173));
        }

        public getPersonList(): App.Person[] {
            return this.persons;
        }

        public getPerson(personId: number): Person {
            var person: Person;

            this.getPersonList().forEach(value => {
                if (value.id === personId) {
                    person = value;
                }
            });

            return person;
        }

        //#region Angular Module Definition
        private static _module: ng.IModule;
        /**
        * Stellt das aktuelle Angular Modul für "ServiceName" bereit.
        */
        public static get module(): ng.IModule {
            if (this._module) {
                return this._module;
            }

            //Hier die Abhängigen Module für diesen Service definieren.
            this._module = angular.module('TodoService', []);
            this._module.service('TodoService', TodoService);
            return this._module;
        }
        //#endregion
    }
} 

5. Einrichten einer ControllerAs Direktive

Auch in der Definition der Direktive gibt es wieder eine Modul Definition und alle bekannten Properties die zu einer Direktive gehören.

module App.Directives {

    /* 
	* Definition der "Scope" Variablen für die CtrlAsDirectiveName Directive
	*/
    export interface ICtrlAsDirectiveNameScope {
        sqTitle: string;
        isDeleted: boolean;
        model: string;
    }

    /*
	* Beschreibung
	*
	* Verwendung: 
	*  <div></div>
	*/
    export class CtrlAsDirectiveName implements ng.IDirective {
        public restrict: string = "A";
        public replcae: boolean = true;
        public require = "ngModel";
        //public templateUrl: string = 'ScriptsApp/directives/templates/CtrlAsDirectiveName.directives.html';
        public template: string = '<a class="btn btn-default" title="{{ctrl.sqTitle}}">Test Counter: {{ctrl.counter}}</a>';
        public scope = {}

        public controller = CtrlAsDirectiveNameCtrl;
        public controllerAs = "ctrl";
        public bindToController = {
            sqTitle: "=", 
            isDeleted: "=",
            model : "=ngModel"
        }

        //constructor(private $interval: angular.IIntervalService) { }
        constructor() { }

        public link = ($scope: any, element: JQuery, attrs: ng.IAttributes, model: ng.INgModelController) =&gt; {

        }


        //#region Angular Module Definition
        private static _module: ng.IModule;
        /**
        * Stellt die Angular Module für CtrlAsDirectiveName bereit.
        */
        public static get module(): ng.IModule {
            if (this._module) {
                return this._module;
            }

            //Hier die abhängigen Module für unsere Direktive definieren.
            this._module = angular.module('ctrlAsDirectiveName', []);
            //this._module.directive('CtrlAsDirectiveName', ["$interval", ($interval: angular.IIntervalService) =&gt; { return new CtrlAsDirectiveName($interval); }]);
            this._module.directive('ctrlAsDirectiveName', [() =&gt; { return new CtrlAsDirectiveName(); }]);
            return this._module;
        }
        //#endregion
    }

    /*
	* Implementierung unseres CtrlAsDirectiveName Controllers.
	*/
    export class CtrlAsDirectiveNameCtrl implements ICtrlAsDirectiveNameScope {
        public sqTitle: string;
        public isDeleted: boolean;
        public model: string;
        public counter : number;

        static $inject = [];

        constructor() {
            this.init();
        }

        init(): void {
            this.counter = 0;
        }

        /*
		* Eine Funktion die z.B: über ein btn Click des Templates aufgerufen werden kann
		*/
        public doSomethingBtnClick(): void {
            //Zugriff auf die "Scope" Variable mit "this"
            this.sqTitle = "Blubb";
            this.counter++;
        }
    }
}

6. Einrichten eines Filters

module App.Filter {

    /*
     * Beschreibung 
     * 
     * Verwendung: 
     *
     */
    export class AddPrefixFilter {
     
        static $inject: string[] = ["$sce"];
       
        static filter($sce: ng.ISCEService) {
            return (value, text) => {
                return text + ' ' + value;
            }
        }
      
        //#region Angular Module Definition
        private static _module: ng.IModule;

        /**
        * Stellt die Angular Module für AddPrefixFilter bereit.
        */
        public static get module(): ng.IModule {
            if (this._module) {
                return this._module;
            }

            //Hier die abhängigen Module für unsere Direktive definieren.
            this._module = angular.module('addPrefix', []);
            this._module.filter('addPrefix', App.Filter.AddPrefixFilter.filter);
            return this._module;
        }
        //#endregion
    }
}

Visual Studio 2015 ausgewählte Features


Da Visual Studio 2015 vor kurzem sein erstes großes Update erhalten hat, habe ich mich jetzt auch “getraut” darauf umzusteigen vom VS 2013 auf VS 2015 und ich muss sagen ich möchte es nicht mehr missen. Denn es gibt doch ein paar sehr gute Neuerungen für die sich der Umstieg lohnt, wie ich finde.

Das gute ist, das die alten Solution Files vom VS 2013 auch im VS 2015 noch problemlos geöffnet werden können und man diese danach auch wieder mit VS 2013 öffnen kann, damit kann man bei Bedarf beide Versionen parallel betreiben ohne größere Probleme.

Im Folgenden ein paar Verbesserungen im Visual Studio 2015 die ich aktuelle nicht mehr vermissen möchte.

1. Anzeige der Ausführungszeit zwischen zwei Haltepunkten

Wenn man früher wissen wollte wie lange die Ausführung zwischen zwei Haltepunkten gedauert hat, dann muss man eine Stopwatch einbauen, diese Zeiten sind nun endlich vorbei, denn ab VS 2015 zeigt der Debugger automatisch die Zeit an die zwischen zwei Haltepunkten vergangen ist, direkt hinter dem aktuellen Haltepunkt.

image

oder auch beim durchgehen nach jedem Step (F10)

image

2. Überarbeitetes NuGet Fenster

Auch das aktualisieren und Abrufen von NuGet Paketen wurde komplett überarbeitet und wird jetzt nicht mehr in einem Popup angezeigt, sondern ist direkt in VS integriert. Es lassen sich jetzt auch einzelne Pakete deinstallieren die noch Abhängigkeiten besitzen ohne diese extra zu deinstallieren. Außerdem sieht man ob es im Projekt gleiche Pakete mit einer unterschiedlichen Versionsnummer gibt. Man kann auswählen welche Version man installieren möchte und muss nicht immer nur auf die neueste upgraden, um nur ein paar der Neuerungen der neuen NuGet Version anzusprechen.

image

3. Quellcode im Debugmodus ändern

Leider war es bisher nicht möglich in Webapplikation, beim Debuggen den Quellcode zu ändern und die Seite dann einfach weiterlaufen zu lassen. In VS 2013 musste das Webprojekt dafür noch gestoppt werden. Mit VS 2015 ist es endlich möglich auch beim Debuggen den Code on the fly zu ändern.

4. Code Highlighting im HTML Editor von AngularJs Elementen

Es gibt im HTML Editor zwar immer noch kein IntelliSense für AngularJs Objekte aber für die nativen AngularJs Direktiven wird der Inhalt der Attribute jetzt in einer anderen Farbe dargestellt, damit erkennt man in großen HTML Blöcken jetzt wesentlich leichter die AngularJs “Code Snippets” in den Direktiven.

image

Leider funktioniert das nur bei den nativen AngularJs Kürzeln. Bisher habe ich leider noch nicht herausgefunden ob man das ganze auch für seine eigenen Direktiven wie “my-app” im obigen Screenshot einstellen kann.

5. Debuggen von Lambda Ausdrücken

Endlich kann man Lambda Ausdrücke auch im Quickwatch auswerten und den Inhalt anzeigen lassen.

image

Im Watch kann man diese dann entsprechend anzeigen lassen

image

Oder im “Immediate Window” kann man damit jetzt auch rumspielen

image

6. Verbesserte Tooltips im Code für const und Enums

Auch die Anzeige der Tooltips vom VS 2015 wurde verbessert, so sieht man jetzt z.B. im Tooltip zu einer Kontanten oder einem Enum den Inhalt der Konstanten oder den Wert des ausgewählten Enums.

image

image

7. Speichern des aktuellen Window Layouts

Wer kennt das leidige Problem nicht, man hat einen Laptop auf Arbeit und mehrere Monitore daran angeschlossen und sein VS schön auf alle Monitore verteilt und dann loggt man sich von daheim per Remotedesktop auf Arbeit ein und alles ist im “Ars….”, damit ist jetzt Schluss. Denn mit VS 2015 kann man sein aktuelles Fensterlayout speichern.

image

und ganz einfach wieder laden per Shortcut oder Menüpunkt

image

8. Erweitertes CodeLens ab VS 2015 Professional

Leider ist CodeLens noch nicht in der Community Edition angekommen, aber wer die Professional sein Eigen nennen darf und noch eine aktuelle Quellcodeverwaltung verwendet, der kann sich über eine erweiterte CodeLens Funktionalität freuen.

image

Denn man sieht im CodeLens jetzt auch wer die Funktion als letztes bearbeitet hat und wie viele Änderungen daran insgesamt vorgenommen wurden. Wenn man auf die Änderungen klickt, geht ein kleines OnScreen Fenster mit dem Verlauf dazu auf.