Komponente | – Logik (.ts) – Vorlage HTML (.html) – Style (.scss) |
Decorator | Technisch: Funktion mit vorangestelltem @-Symbol Anwendung: Klassen, Eigenschaften, Methoden und Parameter Beispiel: @HostListener(‚click‘) onHostClick(){/**/} |
Direktiven | Strukturelle Direktiven: manipulieren den DOM (Asterix *) Beispiel: <img *ngIf=“doShowImage“> Attribut-Direktive: verändert das Verhalten oder Aussehen eines Elementes Beispiel: <input matInput> <textarea matAutosizeMinRows =“2″> <input [ngClass]=“inputClass“> |
Pipes | Funktionalität für die Manipulation der Ausgabe (meinstens Verwendung in der VIew) Syntax: Ausdruck | Pipename : Parameter Beispiele: <h2> {{greateTitel | uppercase}}</h2> <h2> {{amount | currency : ‚CHF‘ | lowercase}}</h2> |
angular/core | Basis – Kernfunktionalitäten, „Grundlagen“ – Komponenten und Direktiven – Lebenszyklus – Pipes – Dependency Injection |
angular/common | Bereitstellung allgemeiner Features – standard: Pipes, Direktiven |
angular/platform-browser (AOT) angular/platform-browser-dynamic (JIT) | Steuert Browser und DOM-relevante Bestandteile zum Rendern von Elementen und Verwalten von Ereignissen |
angular/platform-server | SSR – Server side rendering Ideal für Suchmaschinen und Bots |
angular/http | Client-Server-Kommunikation |
angular/forms | Stellt Features für die Formularnutzung zur Verfügung Vorlagen getrieben: FormsModule (Feste Struktur der Formulare) Reaktiv: ReactiveFormsModule (Dynamische Struktur der Formulare) |
angular/router | Ermöglicht die Steuerung und Konfiguration von Routen für Single-Page-Applications Zuordnung Pfad -> Komponente Unter dem <router-outlet Beispiel: Pfad -> auth Komponente -> app-login <router-outlet></router-outlet> <app-login>…</app-login> |
angular/animate | angular/platform-browser/animations Brücke zwischen der Web-Animations-API und der Angular-Welt |
Autor: Thomas J. Fehr
24.02.2022
An den Frieden denken, heisst an die Kinder denken.
Wikipedia: Michail Sergejewitsch Gorbatschow
Der 24.02.2022 beweist wieder einmal mehr wie dumm der Mensch sein kann. Leider nichts aus der Geschichte gelernt.
Warum kämpft man nicht gemeinsam gegen den grössten Feind, der alle Menschen bedroht? Vielleicht wäre es sinnvoller, die Ressourcen zum Retten unseres Planeten Erde zu verwenden, anstelle sich gegenseitig abzuschlachten?
Zum Glück hat die Geschichte uns auch folgendes gelernt:
„Hochmut kommt vor dem Fall“
So long, and thanks for all the fish
Mercury/32 v4.90 released
David Harris hat am 23.10.2021 eine neue Version des Mercury/32 Mailserver veröffentlicht.
Version 4.9 is an important major release containing numerous significant changes and fixes.
https://community.pmail.com/index.php?u=/topic/11469/mercury-32-v4-90-released
Nützliche Links
C#: Factory methode to create new instance
Angenommen, wir haben ein Objekt AppColor, welches uns beim Erstellen der gewünschten Farben hilft. Wir möchten die Möglichkeit besitzen, die Farben über die Parameter Red, Green, Blue und Alpha zu steuern. Weiter brauchen wir verschiedene Möglichkeiten, um das Objekt zu initialisieren – sprich zu erzeugen. Direkt mit allen Parametern RGBA, nur RGB oder den einzelnen Farben. Dies führt dazu, dass wir eine ganze Reihe an Konstruktoren im Objekt haben werden:
public AppColor(byte red = 0, byte green = 0, byte blue=0, byte alpha=0)
{
Red = red;
Green = green;
Blue = blue;
Alpha = alpha;
}
public AppColor(byte red, byte green, byte blue)
{
Red = red;
Green = green;
Blue = blue;
Alpha = 0;
}
public AppColor(byte red)
{
Red = red;
Green = 0;
Blue = 0;
Alpha = 0;
}
...
Eine viel elegantere Lösung können wir mit einer Fabrikmethode (Factory methode) erstellen. Dazu erstellen wir eine Sub-Klasse mit dem Namen Builder, welche sämtliche Parameter als einzelne Methode enthält und als Rückgabewert wieder sich selber enthält. Zusätzlich wird noch eine Methode Create benötigt, welche dann das eigentliche Objekt erstellt:
public class Builder
{
#region fields
private byte _red;
private byte _green;
private byte _blue;
private byte _alpha;
#endregion
#region methodes
public Builder Red(byte red)
{
_red = red;
return this;
}
public Builder Green(byte green)
{
_green = green;
return this;
}
public Builder Blue(byte blue)
{
_blue = blue;
return this;
}
public Builder Alpha(byte alpha)
{
_alpha = alpha;
return this;
}
public AppColor Create()
{
return new AppColor(_red, _green, _blue, _alpha);
}
#endregion
}
Welche Vorteile haben wir nun mit diesem Konstrukt? Jetzt haben wir die Möglichkeit, eine x-beliebige Kombination von Parameter zu verwenden, um das Objekt AppColor zu erstellen:
// Einzelne Farbe
AppColor colorRed = new AppColor.Builder().Red(255).Create();
// Gemischte Farbe
AppColor mixColor = new AppColor.Builder().Red(22).Green(25).Create();
// Gemischte Farbe
AppColor mixColor2 = new AppColor.Builder().Green(25).Blue(12).Create();
// Gemischte Farbe
AppColor mixColor3 = new AppColor.Builder().Red(255).Green(255).Blue(0).Alpha(215).Create();
...
Ganze Klasse
C#: Statements as expressions
if-Statement as expression
Normales if-Statement:
public static decimal GetPriceByStatement(decimal price, int quantity, bool isPremiumMember)
{
decimal discountAmount = 0;
if(quantity >= 12)
{
discountAmount += .1M;
}
if (isPremiumMember)
{
discountAmount += .20M;
}
return price * (1 - discountAmount);
}
Das if-Statement als expression:
public static decimal GetPriceByExpression(decimal price, int quantity, bool isPremiumMember)
{
decimal discountAmount = (quantity >= 12 ? .1M : 0)
+ (isPremiumMember ? .2M : 0);
return price * (1 - discountAmount);
}
swtich-statements as expression
Normales switch-Statement:
public static decimal GetNumberOfAccessLevelStatement(AccessLevels accessLevels)
{
decimal accessLevelNumber = 0;
switch (accessLevels)
{
case AccessLevels.Low:
accessLevelNumber = 100501;
break;
case AccessLevels.LowExtendSecurity:
accessLevelNumber = 100511;
break;
case AccessLevels.Middle:
accessLevelNumber = 100601;
break;
case AccessLevels.MiddleExtendSecurity:
accessLevelNumber = 100611;
break;
case AccessLevels.High:
accessLevelNumber = 100701;
break;
case AccessLevels.HighExtendSecurity:
accessLevelNumber = 100711;
break;
default:
accessLevelNumber = 0;
break;
}
return accessLevelNumber;
}
Das switch-Statement als switch-expression:
public static decimal GetNumberOfAccessLevelExpression(AccessLevels accessLevels)
{
decimal accessLevelNumber = accessLevels switch
{
AccessLevels.Low => 100501,
AccessLevels.LowExtendSecurity => 100511,
AccessLevels.Middle => 100601,
AccessLevels.MiddleExtendSecurity => 100611,
AccessLevels.High => 100701,
AccessLevels.HighExtendSecurity => 100711,
_ => 0,
};
return accessLevelNumber;
}
C#: Zeichenketten richtig vergleichen
Vergleiche die zwei Namen „ROBONAME“ und inputName, aber ignoriere die Gross- und Kleinschreibung.
const string ROBONAME = "iRoby";
string inputName = "IROBY";
if (0 == string.Compare(ROBONAME, inputName, true))
{
Console.WriteLine($"Die Namen {ROBONAME} und {inputName} sind gleich.");
}
Nützliches
C# reference: https://docs.microsoft.com/en-us/dotnet/api/system.string.compare?view=net-5.0
Best practices for comparing strings in .NET: https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings
C#: String-Interpolation
Mit dem Dollar-Zeichen definieren wir, dass es sich um einen „interpolated string“ handelt.
Struktur:
{<interpolationExpression>[,<alignment>][:<formatString>]}
Beispiel: String mit einem formatierten Datum
var msg = $"Datum: {DateTime.Today:dd.MM.yyyy}";
Beispiel: String mit einem formatierten Dezimalwert:
var shortPi = $"Pi is {Math.PI:F3}";
Beispiel mit Sonderzeichen und einem „conditional operator“:
Als Ausgabe erhalten wir:
Nützliches
C# reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
C#: Null-Forgiving Operator (!)
Null-forgiving oder null-suppression operator
Wenn die Null-Prüfung des Compilers aktiviert wurde („enabled nullable annotation context“), wird das Ausrufezeichen „!“ Verwenden, um bewusst einen Nullwert zu erlauben.
Den „nullable annotation context“ aktivieren oder deaktivieren
Null-Prüfung des Compilers ein- ausschalten mit Preprocessor-Direktiven:
#nullable enable
#nullable disable
Die Null-Prüfung kann auch auf der Projektebene in der Projekt-Datei eingeschaltet werden:
Nach dem Aktivieren der Null-Prüfung zeigt der Compiler eine Warnung bei möglichen Nullwerten an:
Sollte ein bestimmter Wert auch Null sein dürfen, haben wir die Möglichkeit, den „Null-Forgiving Operator“ zu verwenden:
Nützliches
C# reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving
C#: Finde die grösste und kleinste Zahl in einem String
Vorgaben
- Der String enthält nur gültige Zahlen getrennt durch ein Leerzeichen und mindestens eine Zahl
- Ausgabe ist ein String mit der grössten und kleinsten Zahl
Beispiele
Eingabe | Ausgabe |
„1 2 3 4 5 6 7 8 9 10“ | „10 1“ |
„-100 99 45 0 1 354“ | „354 -100“ |
Meine erste Lösung
public static string HighAndLow(string numbers)
{
var sortedList = numbers.Split(" ")
.Select(x => Convert.ToDecimal(x))
.OrderByDescending(o => o);
return $"{sortedList.First()} {sortedList.Last()}";
}
Meine zweite optimierte Lösung
public static string HighAndLow(string numbers)
{
var sortedList = numbers.Split(" ").Select(int.Parse);
return $"{sortedList.Max()} {sortedList.Min()}";
}
Unit-Test
public void GetHighAndLowTest()
{
Assert.AreEqual("354 -100", Snippets.HighAndLow("-100 99 45 0 1 354"));
Assert.AreEqual("10 1", Snippets.HighAndLow("1 2 3 4 5 6 7 8 9 10"));
Assert.AreEqual("1 1", Snippets.HighAndLow("1"));
Assert.AreEqual("3002 -68", Snippets.HighAndLow("-68 3001 3 5 -5 " +
"42 3002 -1 0 0 -9 4 7 4 -4"));
Assert.AreEqual("42 -9", Snippets.HighAndLow("8 3 -5 42 -1 0 0 -9 4 " +
"7 4 -4"));
}
C#: Sortiere die Wörter im String anhand ihrer enthaltenen Zahl
Vorgaben
- Der String enthält verschiedene Wörter, getrennt durch ein Leerzeichen, welche richtig sortiert einen Satz ergeben
- Jedes Wort hat an beliebiger Stelle eine Zahl, welche die Position im Satz angibt
- Wenn der Eingabe-String leer ist, gibt die Funktion einen leeren String zurück
- Der Eingabe-String enthält nur gültige Werte
Beispiel
Eingabe | Ausgabe |
Ap7fel h2abe Ic1h un4d Hung3er 5möchte ein6 | Ic1h h2abe Hung3er un4d 5möchte ein6 Ap7fel |
Meine erste Lösung
public static string OrderWordsByNumber2(string words)
{
if (string.IsNullOrWhiteSpace(words)) return string.Empty;
return String.Join(" ", words.Split(" ")
.Select(x => new { word = x, pos = x.First(v => Char.IsDigit(v)) })
.OrderBy(x => x.pos)
.Select(x => x.word));
}
Meine zweite optimierte Lösung
public static string OrderWordsByNumber(string words)
{
if (string.IsNullOrWhiteSpace(words)) return string.Empty;
return String.Join(" ", words.Split(" ")
.OrderBy(x => x.ToList().First(v => Char.IsDigit(v)))); }
}
Unit-Test
[Test]
public void DuplicateCountTest()
{
Assert.AreEqual("1Das is2t ei3ne spannend4e Aufgabe5",
Snippets.OrderWordsByNumber("Aufgabe5 1Das ei3ne is2t spannend4e"));
Assert.AreEqual("Ic1h h2abe Hung3er un4d 5möchte ein6 Ap7fel",
Snippets.OrderWordsByNumber("Ap7fel h2abe Ic1h un4d Hung3er 5möchte ein6"));
Assert.AreEqual("", Snippets.OrderWordsByNumber(""));
}