EventHandler in C#

Oftmals werden Delegaten als eine Art Benachrichtigungsmechanismus für Objekte eingesetzt. Ein Objekt könnte einen beliebigen Zustand erreichen und dann alle Zielmethoden, auf die ein Delegat verweist, ausführen. Das Ganze ist zwar sehr leicht umsetzbar, aber an der Stelle gibt es bei größeren Projekten oftmals ein Problem: Der Kommunikationsmechanismus wird immer wieder verändert.
Am Anfang mag es vielleicht ausreichen, wenn man zum Beispiel nur ein Datum als Parameter übergeben möchte. Aber wenn man im Laufe der Entwicklung weitere Parameter hinzufügt, muss man die Signaturen von allen Methoden, auf die der Delegat verweisen kann, anpassen. Und das sind oft nicht wenige...

Glücklicherweise hat uns Microsoft ein spezielles Pattern vorgegeben, welches wir für genau solche Fälle verwenden können: den EventHandler.
Der EventHandler ist ein Delegat, der zwei vorgegebene Parameter hat: object sender und EventArgs e. Das Objekt der Klasse EventArgs beinhaltet Daten, die mit dem aktuellen Ereignis zu tun haben. Alternativ können wir auch eine eigene Argumentenklasse definieren. Das Objekt sender beinhaltet den Auslöser des Events. Das könnte zum Beispiel ein Button in WPF sein. Mit diesen 2 vordefinierten Parametern können wir so gut wie alle Fälle abdecken: Wir haben Informationen über den Auslöser des Events und wir können beliebige Informationen in Form einer Argumentenklasse weitergeben. Das folgende Beispiel soll die Funktionsweise des EventHandlers verdeutlichen:

        public class MeineArgumente

        {

            public int Zahl { get; set; }

            public string Text { get; set; }

        }

 

        public delegate void VarianteAlt(int zahl, string text);

        public delegate void VarianteBesser(object sender, MeineArgumente e);


        public static EventHandler VarianteIdeal;

        public static EventHandler<MeineArgumente> VarianteIdealArg;

 

        static void Main(string[] args)

        {

            VarianteAlt del1 = new VarianteAlt(A);

            VarianteBesser del2 = new VarianteBesser(B);

            VarianteIdeal+= C;

 

            VarianteIdealArg += B;

        }

 

        private static void A(int zahl, string text)

        {

            Console.WriteLine("A");

        }

        private static void B(object sender, MeineArgumente e)

        {

            Console.WriteLine("B");

        }

        private static void C(object sender, EventArgs e)

        {

            Console.WriteLine("C");

        }

In diesem Beispiel habe ich 4 Delegaten erstellt: VarianteAlt und VarianteBesser als eigene Delegaten-Typen und zwei EventHandler, davon einer in der generischen Variante.

Dem Delegaten vom Typ VarianteAlt übergeben wir die Methode A, die zwei Parameter benötigt. Der Delegat vom Typ VarianteBesser verwendet das von Microsoft empfohlene Pattern: Ein Objekt für den Auslöser und eine Klasse, in der alle sonstigen Daten, die Übermittelt werden, zusammengesammelt werden (MeineArgumente).
Dieses Pattern gibt es auch bereits in der Form des EventHandlers. Der EventHandler VarianteIdeal verwendet im Vergleich zu VarianteBesser eine eigene Argumentenklasse. Wenn man die Argumentenklasse MeineArgumente weiterverwenden möchte, kann man auch die generische Variante verwenden: VarianteIdealArg.
Aufgrund der identischen Signatur können sowohl VarianteBesser als auch VarianteIdealArg auf die Methode B verweisen.

Der Vorteil des EventHandlers liegt hier klar auf der Hand. Wir müssen uns keinen neuen Delegaten-Typen erstellen und brauchen uns keine Sorgen um die Signaturen machen. Wenn man viele Parameter übergeben muss, bietet sich oftmals die Verwendung einer eigenen Klasse an, die alle Parameter zu einem Objekt vereint. Wie das Ganze dann in Kombination mit den namensgebenden Events aussieht, werde ich in einem künftigen Artikel erleutern.

SCCM 2012 R2: Elemente nach Excel exportieren

Durch einen Hinweis wurde ich kürzlich auf eine ziemlich praktische Funktion aufmerksam. Stellen wir uns vor, wir brauchen “schnell” alle Geräte mit einer gemeinsamen Eigenschaft oder einfach alle Geräte einer bestimmten Sammlung. Und zwar möglichst in Excel, um diese an Kollegen weitergeben oder weiter verarbeiten zu können. Natürlich kann man nun einen entsprechenden Report erzeugen und dessen Ergebnis in XLS oder CSV abspeichern – aber es geht auch einfacher. Da hier ein Video mehr als viele Worte oder Bilder sagt, habe ich kurzerhand einen kurzen Clip erstellt. Seht selbst!

 

Hier das Ganze nochmal als direkter Link zu YouTube: https://www.youtube.com/watch?v=CANVBrIEuGE

In Kurzform und wenigen Worten: Man kann die Elemente (bspw. Geräte) markieren (geht mit STRG+A, oder auch mit STRG/SHIFT und Mausklick), mit STRG+C kopieren und dann eben mit STRG+V in Excel einfügen…

ASP.NET doppeltes Title Element

Nachdem ich heute die Bing Webmaster Tools mal mit der https://ppedv.de website Probiert habe, wird mir in allen ASPX Seiten ein doppelter Page Title Fehler angezeigt.

In der Tat wird nach dem CSS das per Theme eingebunden wird, ein leerers Title Element in den HMTL Code eingefügt.

image_thumb

Da wir vor Jahren schon mal einen diesbezüglichen Fehler in der Seite hatten, konnte ich ausschließen, das es sich um einen Coding Fehler handelte. Weiters ist beim einbinden per link der CSS Datei die Kontrolle schon lange im ASP.NET Stack. Es muss sich über ein Update ein Veränderung des Verhaltens ergeben haben. Die entsprechende Suche ergab, auch andere haben das Problem des doppelten Page Titels mit ASP.NET Webforms.

Die Lösung:

Masterpage enthält vor dem ContentPlaceholder einen leeren Page Title ala

   1:  <head runat="server">
   2:      <meta name="viewport" content="width=device-width, initial-scale=1.0">
   3:      <title runat="server" visible="false"></title>
   4:      <asp:ContentPlaceHolder ID="PlaceHolderHead" runat="server">
   5:      </asp:ContentPlaceHolder>

Wenn kein Title Element gesetzt ist, wird von ASP.NET am Ende des Head Elements autoamtisch  ein leerer TITLE eingefügt.

Lambda Expressions

Mein Kollege Michael Zöhling hat vor ein paar Tagen einen Eintrag geschrieben der sich mit dem Thema Delegates in C# befasst.

Ich möchte daran ansetzen und erklären, welchen Zusammenhang Delegates mit Lambda Expressions haben.

Wie wie aus Michaels Beitrag gelernt haben, können wir also eine Methode in einer Variable vom Typ Action<T> oder Func<T> speichern, solange die Signatur (Rückgabewert und Parameterliste) des Delegates gleich ist mit der Signatur unserer Methode.

static void Main(string[] args)
{
Func<int, int, double> plus = Addition;

double summe = plus(8, 10);
}

private static double Addition(int operator1, int operator2)
{
return operator1 + operator2;
}

Oft gibt es jedoch den Fall, dass man diese Methode nur genau ein einziges Mal aufrufen will. In dem Fall ist es ja fast ein bisschen viel Aufwand eine selbstständige Methode zu schreiben, sich einen passenden Namen zu überlegen (schließlich ist ja das Namen vergeben meistens das schwerste Zwinkerndes Smiley). Darum schauen wir uns mal an, wie man den Namen weglassen kann – Wir bauen also eine anonyme Methode.

static void Main(string[] args)
{
Func<int, int, double> plus = delegate (int operator1, int operator2)
{
return operator1 + operator2;
};

double summe = plus(8, 10);
}

Eine Lambda Expression ist im Prinzip nichts anderes mehr, als das ganze bisschen abgekürzt.
Wir verzichten einfach mal auf den Operator delegate und da wir ja faul sind lassen wir auch gleich die zwei Datentypen weg.
Dafür müssen wir jedoch den Lambda Operator anfügen.

static void Main(string[] args)
{
Func<int, int, double> plus = (operator1, operator2) =>
{
return operator1 + operator2;
};

double summe = plus(8, 10);
}

Das wäre somit unser erste Lambda Expression – jedoch können wir das alles noch bisschen kürzen.

static void Main(string[] args)
{
Func<int, int, double> plus = (a, b) => a + b;

double summe = plus(8, 10);
}

In einem weitern Blogeintrag werde ich die Verwendung von Lambdas in der Praxis mit Linq zeigen.

WPF virtuelles Touch Keyboard

Wer eine WPF Anwendung auf einem Tablet Computer betreiben will, stößt schnell auf Probleme mit der virtuellen Tastatur. Um das OnScreen Keyboard zu aktivieren kann tabtip.exe ausgeführt werden.

Windows 10 bringt aber nun einen Tablet Modus, der weitestgehend das Keyboard automatisch einblendet, wenn der Benutzer den Finger in eine Input Box setzt. Im Desktop Modus von Windows 10 lässt sich dieses per Task Leiste Symbol einblenden.

image

Per XAML Attribut InputScope kann die WPF Anwendung steuern, welches Keyboard Layout verwendet wird. Number zeigt den Ziffernblock, EmailSmtpAddress das @ Zeichen.

image

Eine WPF Anwendung im Tablet Modus wird automatisch im Vollbild Modus ausgeführt. Manchmal erscheint keine Tastatur, dann hilft der Wechsel in eine UWP App, zb Cortana, um das Keyboard zu aktivieren. Allerdings überdeckt die Tastatur die Desktop Anwendung in der unteren Hälfte und damit auch dortige Eingabe Felder.

SCCM: Neue Version 1601 released

Wenn man auch noch nicht viel darüber im Internet findet, so kann man aber auf der Webseite des gut informierten SCCM-MVP Niall C. Brady nachlesen, dass heute die Technical Preview vom System Center Configuration Manager in Version 1601 erschienen ist:

https://www.niallbrady.com/2016/01/27/update-1601-now-available-in-system-center-configuration-manager-technical-preview/

Details werde ich in den kommenden Tagen noch ergänzen…

Delegates in C#

Insbesondere in der objektorientierten Welt von .NET hat man oftmals die Anforderung Code auszuführen, der an einer vollkommen anderen Stelle definiert ist oder dessen genauen Inhalt man nicht kennt. Ich wurde schon in vielen Kursen von meinen Teilnehmern gefragt, welche Möglichkeiten uns in diesem Fall zur Verfügung stehen. In solchen Fällen bietet sich oft die Verwendung von Delegaten an. Ein Delegat ist an sich nur ein Datentyp, der auf eine Methode zeigt. Der Aufrufer der Methode wird also zur Laufzeit mit der Zielmethode verbunden. Eine mitgegebene Liste an Parametern fungiert hierbei als Signatur für die Art von Methoden, auf die einen Delegaten verweisen darf.

Hier müssen wir zwischen den zwei Ausprägungen eines Delegaten unterscheiden: Typ und Instanz.

Ein Delegat-Typ definiert sozusagen die „Vorlage“, an das sich der Aufrufer und das Ziel halten müssen. Hier werden Rückgabetyp und die Parameter definiert.
Eine Delegat-Instanz ist ein Objekt, welches sich auf eine oder mehrere Zielmethoden bezieht. Dieses Objekt entspricht der vorher definiertem „Vorlage“.

Die Deklaration eines Delegates beginnt mit dem delegate Schlüsselwort, gefolgt vom Rückgabetyp, dem Namen des Delegat-Typen und der Parameterliste.

delegate void MyDelegate(int x);

Um eine Delegat-Instanz zu erstellen, muss man einer Delegat-Variable eine Methode zuweisen. Dies kann zum Beispiel folgendermaßen aussehen:

        static void Main(string[] args)

        {

            MyDelegate d = new MyDelegate(A);

            d(12);

        }

 

        static void A(int x)

        {

            // Hier passiert etwas ...

        }   

Nachdem man der Delegat-Variable eine Methode zugewiesen hat, kann man mit ihr die hinterlegte Methode aufrufen.

Wenn man innerhalb seiner Anwendung einen Delegaten benötigt, der auf eine Methode zeigt, die einen oder mehrere Parameter hat, jedoch keinen Rückgabetyp benötigt, kann man entweder seinen eigenen Delegaten schreiben oder den bereits vordefinierten generischen Action<T> - Delegaten aus dem .NET Framework nutzen. Mithilfe des Action<T> - Delegaten können wir Methoden ausführen, die bis zu 16 Parameter haben.

        static void Main(string[] args)

        {

            var act = new Action<int, int>(B);

            act(1,2);

        }

 

        static void B(int zahl1, int zahl2)

        {

            Console.WriteLine(zahl1 + zahl2);

        }

 

Im obrigen Codebeispiel wird ein Action<T> - Delegat mit zwei Integer Parameter erstellt, der auf die Methode B verweist. Beim Aufruf des Delegaten wird die Methode B ausgeführt und die Summe der übergebenen Parameter in die Konsole hineingeschrieben.

 

Für Methoden, die einen Wert zurückgeben, kann man den generischen Func<T> - Delegaten verwenden. Der Func<T> - Delegat kann, wie der Action<T> - Delegat, bis zu 16 Parameter nutzen. Der letzte generische Eintrag ist üblicherweise der Rückgabetyp.

 

        static void Main(string[] args)

        {

            var fun = new Func<int, int, string>(C);

            Console.WriteLine(fun(5, 3));

        }

 

        static string C(int zahl1,int zahl2)

        {

            return ("Das Ergebnis ist " + (zahl1 + zahl2)).ToString();

        }

 

In diesem Codebeispiel wird ein Func<T> - Delegat erstellt, der zwei Integer-Zahlen als Parameter verlangt und eine Rückgabe in Form eines Strings zurückgibt. Der String beinhaltet die Summe der übergebenen Zahlen mit einem Begleittext. Dieser Text wird nach dem Aufruf der Methode C in die Konsole hineingeschrieben.

 

Nun wird man sich sicherlich fragen, welche der Varianten man nun am besten nutzen sollte.

Prinzipiell könnte man, wenn man sich ein wenig Schreibarbeit sparen möchte und nicht mehr als 16 Parameter benötigt, die Action<T>und Func<T> Delegaten ohne Probleme verwenden. Jedoch sind die Modifizierer out und ref für die Parameter bei Action<T>und Func<T> nicht nutzbar. Für diesen Fall müsste man sich den Delegaten selbst schreiben.

 

Ein weiteres sehr nützliches Feature ist das Verketten von Delegaten. Mithilfe des += Operators kann man mit einem Delegaten nicht nur auf eine, sondern auf mehrere Zielmethoden verweisen.  Es ist hierbei sogar möglich, mehrere Delegate-Instanzen miteinander zu verketten. Dies wird im folgenden Beispiel kurz vorgestellt:

 

        delegate void MyDelegate(int x);

 

        static void Main(string[] args)

        {

            MyDelegate del1 = A;

            MyDelegate del2 = C;

 

            del1 += B;

            del1 += del2;

 

            del1(12);

        }

 

 

        static void A(int x)

        {

            Console.WriteLine(x);

        }

        static void B(int x)

        {

            Console.WriteLine(x * 2);

        }

        static void C(int x)

        {

            Console.WriteLine(x * 3);

        }

 

Hier werden 2 Delegaten erstellt, die je auf die Methode A und C zeigen. Die Methode B und C werden dann mithilfe des += Operators augenscheinlich an den Delegaten del1 angehängt. In Wirklichkeit wird im Hintergrund immer eine neue Delegat-Instanz erstellt, die der Variable del1 zugewiesen wird. Dies liegt an der Tatsache, dass Delegaten an sich unveränderliche Objekte sind. In C# werden daher für die Delegaten die += und -= Operationen in die statischen Methoden Combine() und Remove() der Klasse System.Delegate umgewandelt.

Mit dem Aufruf von del1 werden die Methoden A, B und C der Reihe nach ausgeführt. Die Reihenfolge hängt in erster Linie davon ab, wann eine Methode „angehängt“ wird.

Delegaten werden insbesondere im Zusammenhang mit Events sehr häufig verwendet. In einem künftigen Blogeintrag werde ich dann auf die genauen Zusammenhänge von Delegaten und Events eingehen.

SCCM: Verwaltung von Clients in nicht-vertrauten Domänen und in Workgroups

Am leichtesten ist es für den Administrator natürlich, wenn alle verwalteten Geräte in der selben Domäne stehen. Aber der System Center Configuration Manager ist auch in der Lage, mit Geräten umzugehen, die außerhalb der eigenen Gesamtstruktur (“Forest”) in einer nicht-vertrauten Domäne (“Non-trusted Domain”) oder sogar nur in einer Arbeitsgruppe (“Workgroup”) stehen. Dafür sind ein paar Voraussetzungen zu erfüllen und ein paar Besonderheiten bei der Einrichtung zu beachten.

Voraussetzungen:

  • Geräte der nicht-vertrauten Domäne (“nvD”) oder der Workgroup (“WG”) können den gewünschten Verwaltungspunkt (“Management Point”, MP) per DNS auflösen
  • Verwaltete Geräte in der nvD und/oder der WG können von den Standortsystemservern (“Site Server”) des SCCMs aufgelöst werden (bei nvD zusätzlich der Domänen-Name der nvD)
  • Das Konto der Client-Push-Installation hat ausreichend Rechte auf den Zielcomputern
    • Bei nvD ist ein Domänen-Account der nvD nötig, der auf den Clients lokale Admin-Rechte hat
    • Bei WG-Computern ist ein lokales Admin-Konto nötig, dass auf jedem WG-Computer gleich konfiguriert ist (Name / Passwort)

Um nun den Configuration Manager Client auf einem Gerät in einer Workgroup hinzuzufügen, kann die Push-Installation verwendet werden. Dazu muss a) die Firewall des PCs entsprechend geöffnet werden und b) ein passendes (lokales!) Konto als Push-Installations-Konto hinterlegt werden (Mehrere Konten möglich!):

wg1

Außerdem ist es notwendig, ein passendes Netzwerkzugriffskonto (“Network Access Account”) im SCCM zu hinterlegen, denn das Computerkonto des WG-Systems hat ja keine Leserechte auf den Site-Servern der Domäne:

wg1

Nun kann der Client mittels Pushinstallation (oder auch händisch!) verteilt werden und Software und co. auf den Arbeitsgruppen-PCs bereitgestellt werden.

Für die Verwaltung von Computern in einer nicht-vertrauten Domäne (nvD) muss zunächst die Gesamtstruktur der nvD bekannt gemacht werden:

nvd1

nvd2

Außerdem muss die “Active Directory Systemermittlung” um die externe Domäne (nvD) ergänzt werden:

nvd3

nvd4

Damit können denn Geräte der externen Domäne gefunden werden – und später per Push-Installation (siehe oben) mit dem Client betankt und somit verwaltet werden.

Hinweis: Für den Aufbau einer Secondary Site in einer externen Domäne ist eine bidirektionale Vertrauensstellung notwendig! (Two-Way-Trust)

HTML5 - Web Workers

Ich dachte mir, dass es doch keine schlechte Idee ist, euch mal einen kleinen Einblick in die Welt der Web Worker zu geben. Dazu gibt es ein kleines Beispiel und ein paar Worte, was denn diese Web Worker eigentlich sind.

In JavaScript war es immer ein Problem wenn es um Nebenläufigkeit ging. Die Sprache selbst ist eine Single-Threaded-Umgebung. Das bedeutet, dass alle möglichen Dinge im selben Script ablaufen und der Nutzer somit teilweise nichts anderes mehr auf der Seite machen konnte. Ich denke, viele von euch kennen dieses tolle Dialogfenster, oder?

NichtreagierendesScript

Mit Hilfe von setTimeout(), setIntervall(), XMLHttpRequest und EventHandlern konnte eine Nebenläufigkeit nachgeahmt werden. Diese Funktionen laufen zwar alle asynchron ab, sind blockierungsfrei aber dies bedeutet nicht, dass es auch parallel ist. Asynchrone Ereignisse werden verarbeitet, nachdem das aktuelle Ausführungsskript ausgesetzt wurde. In HTML5 gibt es nun eine tolle, bessere Lösung für solche Dinge.

Hier kommen nun die Web Worker ins Spiel. Ein Web Worker erzeugt Threads im Hintergrund der Webanwendung. Zum Beispiel ermöglicht es uns rechenintensive Scripts auszuführen ohne gleich unsere Benutzeroberfläche oder andere Scripts zu blockieren.

Ich zeige euch nur ein ganz kleines Beispiel. Für gewöhnlich benutzt man Web Worker nicht für solche Kleinigkeiten aber um zu verstehen, wie sie funktionieren, reicht auch ein kleines Script aus.

Da es sich um einen isolierten Thread handelt, bekommt der Worker seine eigene .js-Datei. Das Objekt des Workers selbst, erstellen wir trotzdem auf unserer Hauptseite. Was genau haben wir nun eigentlich vor? Ganz einfach, wir werden schnell zwei Buttons erstellen zum Starten und Stoppen des Workers. Drücken wir auf Start, so soll der Worker einen Counter starten. Ein Druck auf Stopp beendet ihn.

1 <!DOCTYPE html> 2 <html> 3 <body> 4 5 <p>Count numbers: <output id="result"></output></p> 6 <button onclick="startWorker()">Start Worker</button> 7 <button onclick="stopWorker()">Stop Worker</button> 8 <br><br> 9 10 <script> 11 12 var w; 13 14 function startWorker() { 15 if(typeof(Worker) !== "undefined") { 16 if(typeof(w) == "undefined") { 17 w = new Worker("../JS/WebWorkerBlog.js"); 18 } 19 w.onmessage = function(event) { 20 document.getElementById("result").innerHTML = event.data; 21 }; 22 } else { 23 document.getElementById("result").innerHTML = "Sorry! No Web Worker support."; 24 } 25 } 26 27 function stopWorker() { 28 w.terminate(); 29 w = undefined; 30 } 31 </script> 32 33 </body> 34 </html>

 

Was geschieht hier nun eigentlich? Drücken wir auf Start, überprüfen wir zunächst, ob unser Browser überhaupt in der Lage ist, Web Worker auszuführen. Unterstützt er sie nicht, bekommen wir die einfache Ausgabe: “Sorry! No Web Worker support.”

Wenn er sie unterstützt, überprüfen wir ob schon ein Worker existiert. Ist dies nicht der Fall, wird ein neuer erstellt. Dies geschieht ganz einfach über den Konstruktor des Workers mit der Pfadangabe der .js-Datei, in der unserer auszuführender Code liegt. Wie genau dieser Code aussieht, zeige ich gleich. Doch zunächst schauen wir erst mal weiter auf unsere Hauptseite. Im Code befindet sich ein EventHandler mit dem Namen “onmessage”. Der Worker wartet nach seiner Erstellung auf Nachrichten. Bekommt er eine, so reagiert der EventHanlder. In unserem Fall schreibt er die erhaltene Nachricht in den <output>-Tag mit der ID: “result”. Die Daten des Worker werden in “Event.data” gespeichert. Drücken wir auf Start, wird also solange(in diesem Beispiel jedenfalls) der Code ausgeführt, bis wir auf Stopp drücken. Damit wir wissen, was unserer Worker da überhaupt genau macht, werfen wir nun einen Blick in das entsprechende Script.

1 var i = 0; 2 3 function Counter() { 4 i = i + 1; 5 6 //Sendet eine Nachricht zurück an die HTML-Seite 7 8 postMessage(i); 9 setTimeout("Counter()", 1000); 10 } 11 12 Counter();

 

Sieht nicht sonderlich spektakulär aus, reicht aber. Hier befindet sich nun die Funktion unseres Workers. Wird er gestartet, führt er diese paar Zeilen Code aus. Alle 1000ms ruft er erneut die Methode “Counter” auf, und schickt das Ergebnis per “postMessage()” zurück an die Hauptseite. Jetzt springt in der Hauptseite der EventHandler an, nimmt die Nachricht entgegen und gibt sie uns im Browser aus. Der wichtigste Part hier ist die “postMessage()” Methode. Mit ihr werden Nachrichten ( oder auch JSON-Objekte) weitergeleitet. Wir können damit auch von der Hauptseite aus Nachrichten an die Worker-Datei senden und nicht nur von der Worker-Datei zur Hauptseite. Dazu brauchen wir nur das Worker-Objekt in der Hauptseite mit der “postMessage()” Methode ansprechen: “w.postMessage(“Hallo Worker”);”

Der Worker selbst wartet die ganze Zeit auf Nachrichten. Selbst dann, wenn das externe Script schon fertig ist. Um die Ressourcen freizugeben, muss der Worker beendet werden. Das können wir, wie in diesem Bespiel, über die Hauptseite per “w.terminate()” oder im Worker mit der “close()” Methode machen. Für gewöhnlich ist der Worker ganz beendet. Unsere Buttons würden nicht mehr funktionieren. Damit wir hier den Code aber erneut verwenden können, setzen wir ihn ganz einfach zurück. Das passiert in der “stopWorker()” Methode in der Hauptseite. Wir setzen unsere Variable “w” wieder auf “undefined” und können so den Code erneut nutzen.

Der Worker selbst kann aber nicht auf alle JavaScript-Funktionen zugreifen. Wir haben keinen Zugriff auf folgende Dinge: “window”-Objekt, “document”-Objekt, “parent”-Objekt.

Ich hoffe, der kleine Einblick war hilfreich für euch. Die Web Worker sind noch umfangreicher als hier dargestellt und das werden wir uns zu einem späteren Zeitpunkt noch etwas genauer anschauen. 

Angular 1.5 Components vs Direktiven

Zum Zeitpunkt des Blog Artikels befindet sich Angular.js 1.5 in der RC0 Phase. Trotz des kommenden (und völlig anderen) Angular 2 wird weiter am 1er Zweig gearbeitet. In jeder meiner bisherigen Angular Schulungen, waren Direktiven eine echte Hürde für die Teilnehmer. So kommt nun ein etwas einfachere Variante mit den Components in der Version 1.5. Überdies ähnelt die Verwendung auch den Components von Angular 2 und wird als Umstiegshilfe gesehen.

Komponenten werden als HTML Erweiterungen betrachtet, analog zu den Direktiven. Beide beschreiben das Verhalten eines kleinen Teils der Single Page Application Website. Erster Unterschied ist, das Komponenten nur als Elemente verwendet werden können. Der Erste Parameter identifiziert das neue HTML Element in der Angular Camel Case Notation. Der zweite Parameter enthält die Optionen und nicht eine Funktion (mit Rückgabeobjekt) wie bei der Direktive.

   1:  angualar.module("App")
   2:  .component(name, options);

Folgende Optionen können übergeben werden

controller – Name  der oder Konstructor Funktion
controllerAs – Controller Alias
template – html Zeichenkette oder als Funktion die eine html Template Zeichenkette zurück gibt
templateUrl – Zeichenkette oder Funktion die auf eine HTML Datei verweist
bindings – JavaScript Object {} Bindungen zwischen DOM Attributen und den Component Eigenschaften des Component Controllers
transclude – innere ersetzung des HTML Templates mit HTML aus Template Referenzierung (bool)
$... – {function()=} – Factory Funktion

 

Als nächstes ein Beispiel einer Angular Component. Der Wert des HTML Attributes count wird im lokalen scope des Controllers zugewiesen. Der Controller zeigt auf eine inline Funktion, die eine Methode plus bereit stellt. Im Template wird in der Notation Komponenten Name . Controller Eigenschaft/Methode die Bindung an das Viewmodel deklariert.

   1:  .component('counter', {
   2:          bindings: {
   3:            count: '@'
   4:          },
   5:          controller: function() {
   6:            this.plus = function {
   7:              this.count++;
   8:            };
   9:          },
  10:          template: '<div><input type="text" ng-model="counter.count">
<button type="button" ng-click="counter.plus();">+</button></div>'
  11:    })

In der Praxis wird wahrscheinlich im HTML Code ein zum View gehöriger Controller, das Viewmodel bereitstellen.  Entsprechend wird dem count Attribut des Counter kein Wert zugewiesen, sondern eine Eigenschaft des Controllers. Hier mit der ControllerAS Syntax als vm bezeichnet.

   1:  <div ng-controller="MainCtrl as vm">
   2:        <h1>Counter</h1>
   3:        <counter count="vm.count"></counter>
   4:      </div>

In Zeile 3 des JavaScript Component Codes wird dann die Bindung mit count :”=” auf die Eigenschaft des Viewmodels durchgereicht. Die ViewModel Eigenschaft Count kann so über vm.count dann in der Sicht Formular weiter gebunden werden.

Windows Server 2016 Training

Month List