Angular-BookMonkey: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(Die Seite wurde neu angelegt: „= Links = * Angular = Schritte = <source lang="bash">ng new BookMonkey -p bm # ... Angular routing: y # Rest: leere Eingabe </source>“) |
|||
(10 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
= Links = | = Links = | ||
* [[Angular]] | * [[Angular]] | ||
* [https://github.com/Kylonas/BookMonkey Github-Quelle des Buchs] | |||
= Schritte = | = Schritte = | ||
< | <syntaxhighlight lang="bash">ng new BookMonkey -p bm | ||
# ... Angular routing: y | # ... Angular routing: y | ||
# Rest: leere Eingabe | # Rest: leere Eingabe | ||
</ | npm install semantic-ui-css | ||
</syntaxhighlight> | |||
* Änderung in angular.json: | |||
** projects -> BookMonkey -> architect -> build -> options -> styles: | |||
** projects -> BookMonkey -> architect -> test -> options -> styles: | |||
<pre> | |||
"styles": [ | |||
"node_modules/semantic-ui-css/semantic.css" | |||
], | |||
</pre> | |||
* neues Interface | |||
<syntaxhighlight lang="bash">ng g interface shared/book | |||
ng g component book-list | |||
ng g component book-list-item | |||
</syntaxhighlight> | |||
* Anpassungen in booklist.component.html | |||
* Anpassungen in booklist.component.js | |||
* Eintrag in app.component.html: <code><bm-book-list></bm-book-list></code> | |||
== Komponente == | |||
* Dekorator @Component | |||
* Initialisierung nicht im Konstruktor, sondern in <code>ngOnInit(): void(){}</code> | |||
* Alle Bausteine der Anwendung werden mittels <code>@NgModule()</code> in Angular-Modulen organisiert. Automatisch mit <code>ng g component...</code> erledigt in app.module.ts. | |||
* Eine Komponte muss immer in ''declarations'' eines Moduls registriert werden. Automatisch mit <code>ng g component...</code> erledigt. | |||
* Verschachtelung von Komponenten über (CSS-)Selektor. | |||
=== Selektoren === | |||
* div.active Div-Element mit CSS-Klasse active | |||
* input[type=text] Eingabefeld vom Typ Text | |||
* li:nth-child(2) jedes zweite Listenelement innerhalb des Elternelements <code><li></code> | |||
* my-element Element mit Tag <code><my-element></code> | |||
* [myAttr] Attribut, z.B.. <code><div myAttr="123"</div></code> | |||
* [myAttr=bar] Attribut, z.B.. <code><div myAttr="bar"</div></code> | |||
* .myClass Elemente mit CSS-Klasse myClass, z.B. <code><div class="myClass"</div></code> | |||
'''Konvention''': möglichst nur Elementnamen verwenden | |||
== Property-Bindings == | |||
* Bringt Daten von der Komponente in Kindelemente im Komponentenbaum. | |||
<pre><my-component [property]="expression"></my-component> | |||
</pre> | |||
* Datenänderung führt automatisch zu Anzeigeaktualisierung | |||
* Auch beliebige Attribute im DOM-Baum sind ansprechbar: | |||
<syntaxhighlight lang="ts">const myImg = document.getElementById('myImg'); | |||
myImg.src = 'angular.src'; | |||
myImg.style.border = '1px solid black'; | |||
</syntaxhighlight> | |||
* HTML-Element ist konstanter Text, Dynamik wird durch Interpolation und die Property-Bindings erzeugt. | |||
* Alternative Schreibweisen: | |||
<pre><!-- Interpolation --> | |||
<element property="{{ expression }}"</element> | |||
<!-- Textkonstante in Ticks einfügen: --> | |||
<element [property]="'value'"></element> | |||
</pre> | |||
=== Beispiele === | |||
<pre><!-- URL und Title werden aus der Komponente x.myUrl bzw. x.myTitle genommen --> | |||
<img [src]="myUrl" [title]="myTitle" /> | |||
<button [disabled]="isDisabled">Do it</button> | |||
<p [textContent]="'DubuDubuDuu'"></p> | |||
<my-component [foo]="1+1"></my-component> | |||
</pre> | |||
=== Weitere Arten von Property-Bindings === | |||
* Attribute-Bindings: Setzen von Attributwerten <code>[attr.colspan]</code> | |||
<pre><td [attr.colspan]="myColSpan"></td> | |||
<a [attr.role]="myRole>Link</a> | |||
</pre> | |||
* Class-Bindings: Zuweisen von CSS-Klassen: <code>[class.myCssClass]</code>, wenn Bedingung ("expression") true ist. | |||
** Alternative <code>[ngClass]</code>, wenn mehrere gleichzeitig zugewiesen werden sollen. | |||
<pre><element [class.myClass]="hasMyClass"></element> | |||
<div [ngClass]="[ active: isActive, 'has-error': hasError, disabled: isDisabled, myClass: hasMyClass }"></div> | |||
</pre> | |||
* Style-Bindings: Hinzufügen von CSS-Stilen: <code>[style.color]</code> | |||
** Mehrere Zuweisungen mittels <code>[ngStyle]</code>. | |||
<pre><! Achtung, funktioniert nicht, da aus Sicherheitsgründen verboten: --> | |||
<element style="color: {{ myColor }}"></element> | |||
<element [style.color="myColor"></element> | |||
<div [ngStyle]="{ 'color': myColor, 'padding': '10px' }"></div> | |||
<div [ngStyle]="myStyles"></div> | |||
</pre> | |||
== Rückfluss DOM-Property in Komponente == | |||
* Import von angular/core | |||
* Dekorator @Input() bzw. @Input('domProperty') ('''nicht empfohlen'''). | |||
* Bei Fehler "has no initializer and is not definitely assigned in the constructor": undefined zulassen (! nach dem Variablennamen). | |||
<syntaxhighlight lang="ts">import { component, Input } from '@angular/core'; | |||
@Component({ | |||
selector: 'my-component'; | |||
templateUrl: './my.compoent.html'; | |||
}) | |||
export class MyComponent { | |||
@Input() domProperty!: string; | |||
@Input('domProperty') myProperty: string; | |||
constructor() { } | |||
} | |||
</syntaxhighlight> | |||
== Event-Bindings == | |||
* Notation: DOM-Event in runde Klammern gesetzt: | |||
<pre><element> (myEvent)="myHandler()"></element> | |||
</pre> | |||
=== Events === | |||
Die Namen der Angular-Events sind nicht die DOM-Namen, z.B. "click" statt "onClick" | |||
* click: einfacher Mausklick | |||
* change: Ändern eines Werts in Formularfeld | |||
* dblclick: Doppelklick | |||
* keyup: Taste wird losgelassen | |||
* focus: Feld bekommt den Fokus (Maus oder Tastatur) | |||
* blur: Feld verliert den Fokus | |||
* keydown: Taste wird gedrückt | |||
* mouseover: Maus wird auf Element bewegt | |||
* moseout: Maus verlässt Element | |||
* contextmenu: Aufruf des Kontextmenüs | |||
* select: Auswahl von Text | |||
* copy, past: Text kopieren oder einfügen | |||
* submit: Formular wird abgeschickt | |||
Beispiel: | |||
<pre><input (keyup)="myKeyHandler($event)" type="text" /> | |||
</pre>@Component({...}) | |||
export class MyComponent { | |||
myKeyHandler(e: KeyboardEvent) { | |||
console.log(e); | |||
} | |||
} | |||
</pre> | |||
=== Events selber definieren === | |||
* Verwenden des Dekorators @Output | |||
* Auslösung durch <code>emit(value)</code> | |||
* In Hauptkomponente einbinden | |||
<pre><event-component (fooEvent)="handleFoo" | |||
</event-component> | |||
</pre> | |||
Beispiel: | |||
<pre><button (click)="handleClick()">foo auslösen</button> | |||
</pre> | |||
<pre>import { Component, EventEmitter, Output } from @angular/core; | |||
@Component({ ... }) | |||
export class EventComponent { | |||
@Output() fooEvent = new EventEmitter<any>; | |||
handleClick() { | |||
this.fooEvent.emit(); | |||
} | |||
} | |||
</pre> |
Aktuelle Version vom 12. März 2023, 07:39 Uhr
Links[Bearbeiten]
Schritte[Bearbeiten]
ng new BookMonkey -p bm
# ... Angular routing: y
# Rest: leere Eingabe
npm install semantic-ui-css
- Änderung in angular.json:
- projects -> BookMonkey -> architect -> build -> options -> styles:
- projects -> BookMonkey -> architect -> test -> options -> styles:
"styles": [ "node_modules/semantic-ui-css/semantic.css" ],
- neues Interface
ng g interface shared/book
ng g component book-list
ng g component book-list-item
- Anpassungen in booklist.component.html
- Anpassungen in booklist.component.js
- Eintrag in app.component.html:
<bm-book-list></bm-book-list>
Komponente[Bearbeiten]
- Dekorator @Component
- Initialisierung nicht im Konstruktor, sondern in
ngOnInit(): void(){}
- Alle Bausteine der Anwendung werden mittels
@NgModule()
in Angular-Modulen organisiert. Automatisch mitng g component...
erledigt in app.module.ts. - Eine Komponte muss immer in declarations eines Moduls registriert werden. Automatisch mit
ng g component...
erledigt. - Verschachtelung von Komponenten über (CSS-)Selektor.
Selektoren[Bearbeiten]
- div.active Div-Element mit CSS-Klasse active
- input[type=text] Eingabefeld vom Typ Text
- li:nth-child(2) jedes zweite Listenelement innerhalb des Elternelements
- my-element Element mit Tag
<my-element>
- [myAttr] Attribut, z.B..
<div myAttr="123"
- [myAttr=bar] Attribut, z.B..
<div myAttr="bar"
- .myClass Elemente mit CSS-Klasse myClass, z.B.
<div class="myClass"
Konvention: möglichst nur Elementnamen verwenden
Property-Bindings[Bearbeiten]
- Bringt Daten von der Komponente in Kindelemente im Komponentenbaum.
<my-component [property]="expression"></my-component>
- Datenänderung führt automatisch zu Anzeigeaktualisierung
- Auch beliebige Attribute im DOM-Baum sind ansprechbar:
const myImg = document.getElementById('myImg');
myImg.src = 'angular.src';
myImg.style.border = '1px solid black';
- HTML-Element ist konstanter Text, Dynamik wird durch Interpolation und die Property-Bindings erzeugt.
- Alternative Schreibweisen:
<!-- Interpolation --> <element property="{{ expression }}"</element> <!-- Textkonstante in Ticks einfügen: --> <element [property]="'value'"></element>
Beispiele[Bearbeiten]
<!-- URL und Title werden aus der Komponente x.myUrl bzw. x.myTitle genommen --> <img [src]="myUrl" [title]="myTitle" /> <button [disabled]="isDisabled">Do it</button> <p [textContent]="'DubuDubuDuu'"></p> <my-component [foo]="1+1"></my-component>
Weitere Arten von Property-Bindings[Bearbeiten]
- Attribute-Bindings: Setzen von Attributwerten
[attr.colspan]
<td [attr.colspan]="myColSpan"></td> <a [attr.role]="myRole>Link</a>
- Class-Bindings: Zuweisen von CSS-Klassen:
[class.myCssClass]
, wenn Bedingung ("expression") true ist.- Alternative
[ngClass]
, wenn mehrere gleichzeitig zugewiesen werden sollen.
- Alternative
<element [class.myClass]="hasMyClass"></element> <div [ngClass]="[ active: isActive, 'has-error': hasError, disabled: isDisabled, myClass: hasMyClass }"></div>
- Style-Bindings: Hinzufügen von CSS-Stilen:
[style.color]
- Mehrere Zuweisungen mittels
[ngStyle]
.
- Mehrere Zuweisungen mittels
<! Achtung, funktioniert nicht, da aus Sicherheitsgründen verboten: --> <element style="color: {{ myColor }}"></element> <element [style.color="myColor"></element> <div [ngStyle]="{ 'color': myColor, 'padding': '10px' }"></div> <div [ngStyle]="myStyles"></div>
Rückfluss DOM-Property in Komponente[Bearbeiten]
- Import von angular/core
- Dekorator @Input() bzw. @Input('domProperty') (nicht empfohlen).
- Bei Fehler "has no initializer and is not definitely assigned in the constructor": undefined zulassen (! nach dem Variablennamen).
import { component, Input } from '@angular/core';
@Component({
selector: 'my-component';
templateUrl: './my.compoent.html';
})
export class MyComponent {
@Input() domProperty!: string;
@Input('domProperty') myProperty: string;
constructor() { }
}
Event-Bindings[Bearbeiten]
- Notation: DOM-Event in runde Klammern gesetzt:
<element> (myEvent)="myHandler()"></element>
Events[Bearbeiten]
Die Namen der Angular-Events sind nicht die DOM-Namen, z.B. "click" statt "onClick"
- click: einfacher Mausklick
- change: Ändern eines Werts in Formularfeld
- dblclick: Doppelklick
- keyup: Taste wird losgelassen
- focus: Feld bekommt den Fokus (Maus oder Tastatur)
- blur: Feld verliert den Fokus
- keydown: Taste wird gedrückt
- mouseover: Maus wird auf Element bewegt
- moseout: Maus verlässt Element
- contextmenu: Aufruf des Kontextmenüs
- select: Auswahl von Text
- copy, past: Text kopieren oder einfügen
- submit: Formular wird abgeschickt
Beispiel:
<input (keyup)="myKeyHandler($event)" type="text" />
@Component({...})
export class MyComponent {
myKeyHandler(e: KeyboardEvent) { console.log(e); }
}
Events selber definieren[Bearbeiten]
- Verwenden des Dekorators @Output
- Auslösung durch
emit(value)
- In Hauptkomponente einbinden
<event-component (fooEvent)="handleFoo" </event-component>
Beispiel:
<button (click)="handleClick()">foo auslösen</button>
import { Component, EventEmitter, Output } from @angular/core; @Component({ ... }) export class EventComponent { @Output() fooEvent = new EventEmitter<any>; handleClick() { this.fooEvent.emit(); } }