From 22f4f1ec798d070d7858d7458f7b1391b142bc8f Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 25 Oct 2023 22:44:48 +0200 Subject: [PATCH 01/66] Template Essentials --- src/app/admin/admin.module.ts | 17 +++++++++ .../donut-list/donut-list.component.ts | 15 ++++++++ src/app/app.component.ts | 35 +++++++++++++++++-- src/app/app.module.ts | 3 +- 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/app/admin/admin.module.ts create mode 100644 src/app/admin/containers/donut-list/donut-list.component.ts diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts new file mode 100644 index 0000000..dcadee7 --- /dev/null +++ b/src/app/admin/admin.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DonutListComponent } from './containers/donut-list/donut-list.component'; + + + +@NgModule({ + declarations: [ + DonutListComponent + ], + imports: [ + CommonModule + ] +}) +export class AdminModule { } + + diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts new file mode 100644 index 0000000..a0e520e --- /dev/null +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-donut-list', + template: ` +

+ donut-list works! +

+ `, + styles: [ + ] +}) +export class DonutListComponent { + +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c11bb60..2750b78 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,8 +1,26 @@ import { Component, OnInit } from '@angular/core'; +import * as events from "events"; @Component({ selector: 'app-root', - template: `
Hello Angular!
`, + template: ` +
+ + +

{{ message }}

+ +

{{ message.length ? message : 'Nothing here...' }}

+ +

+

+

+ +

+

{{ newMessage.length < 12 ? newMessage : 'to big' }}

+ +

+

{{ myTemplateRefVariable.value }}

+
`, styles: [ ` .app { @@ -15,7 +33,20 @@ import { Component, OnInit } from '@angular/core'; ], }) export class AppComponent implements OnInit { + message!: string; + newMessage!: string; + ngOnInit() { - console.log('Hello World!'); + this.message = 'Value on init'; + } + + handleClick(event: MouseEvent) { + console.log(event); } + + handleInput(event: Event) { + const { value } = event.target as HTMLInputElement; + console.log(value); + this.newMessage = value; + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index bde0672..527f123 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,10 +2,11 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; +import { AdminModule } from './admin/admin.module'; @NgModule({ declarations: [AppComponent], - imports: [BrowserModule], + imports: [BrowserModule, AdminModule], bootstrap: [AppComponent], }) export class AppModule {} From 87b2ec7c726214f67281d667bf6d1ff1630c5391 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 25 Oct 2023 22:57:18 +0200 Subject: [PATCH 02/66] Create a Smart Container Component --- src/app/admin/admin.module.ts | 3 +++ src/app/app.component.ts | 16 +--------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index dcadee7..1d720bf 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -8,6 +8,9 @@ import { DonutListComponent } from './containers/donut-list/donut-list.component declarations: [ DonutListComponent ], + exports: [ + DonutListComponent + ], imports: [ CommonModule ] diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2750b78..8de62d4 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,21 +5,7 @@ import * as events from "events"; selector: 'app-root', template: `
- - -

{{ message }}

- -

{{ message.length ? message : 'Nothing here...' }}

- -

-

-

- -

-

{{ newMessage.length < 12 ? newMessage : 'to big' }}

- -

-

{{ myTemplateRefVariable.value }}

+
`, styles: [ ` From 437dc7d703358e35d83359e95f98decadaa49e88 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 19:17:50 +0200 Subject: [PATCH 03/66] Use the NgOnInit Lifecycle Hook --- .../donut-list/donut-list.component.ts | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index a0e520e..3c36a53 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -1,15 +1,51 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; @Component({ selector: 'app-donut-list', template: ` -

- donut-list works! -

+
+ // pipe to json + {{ donut | json }} +
+ {{ donut.name }} + {{ donut.price }} +
+
`, styles: [ ] }) -export class DonutListComponent { +export class DonutListComponent implements OnInit { + // Declaratie hier maar vullen in ngOnInit() + donut!: any; + donuts!: any[]; + constructor() {} + + ngOnInit(): void { + this.donuts = [ + { + id: 'xy12yr', + name: 'Just Chocolate', + icon: 'jus-chocolate', + price: 119, + description: 'For the pure chocoholic.', + }, + { + id: 'zy19yr', + name: 'Glazed Fudge', + icon: 'glazed-fudge', + price: 129, + description: 'Sticky perfection.', + }, + { + id: 'qy19ya', + name: 'Caramel Swirl', + icon: 'caramel-swirl', + price: 129, + description: 'Chocolate drizzled with caramel', + } + ] + this.donut = this.donuts[0]; + } } From 8badf788d87dd17316f429e30558ca8df0f82f6b Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 19:28:30 +0200 Subject: [PATCH 04/66] Type Definitions with Interfaces --- .../admin/containers/donut-list/donut-list.component.ts | 6 ++++-- src/app/admin/models/donut.model.ts | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/app/admin/models/donut.model.ts diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 3c36a53..463a81b 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -1,5 +1,7 @@ import {Component, OnInit} from '@angular/core'; +import { Donut } from "../../models/donut.model"; + @Component({ selector: 'app-donut-list', template: ` @@ -17,8 +19,8 @@ import {Component, OnInit} from '@angular/core'; }) export class DonutListComponent implements OnInit { // Declaratie hier maar vullen in ngOnInit() - donut!: any; - donuts!: any[]; + donut!: Donut; + donuts!: Donut[]; constructor() {} diff --git a/src/app/admin/models/donut.model.ts b/src/app/admin/models/donut.model.ts new file mode 100644 index 0000000..6100bae --- /dev/null +++ b/src/app/admin/models/donut.model.ts @@ -0,0 +1,7 @@ +export interface Donut { + id: string; + name: string; + icon: string; + price: number; + description: string; +} From 03c64e9144893ba6c51cca5a235d6526dd6bf201 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 19:53:45 +0200 Subject: [PATCH 05/66] Create and Render a Dumb Component --- src/app/admin/admin.module.ts | 4 +++- .../donut-card/donut-card.component.ts | 16 ++++++++++++++++ .../donut-list/donut-list.component.ts | 16 +++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/app/admin/components/donut-card/donut-card.component.ts diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 1d720bf..4250f7b 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -1,12 +1,14 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { DonutListComponent } from './containers/donut-list/donut-list.component'; +import { DonutCardComponent } from './components/donut-card/donut-card.component'; @NgModule({ declarations: [ - DonutListComponent + DonutListComponent, + DonutCardComponent ], exports: [ DonutListComponent diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts new file mode 100644 index 0000000..a4f61ed --- /dev/null +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -0,0 +1,16 @@ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'donut-card', + template: ` +

+ donut-card works! +

+ `, + styles: [ + ] +}) +export class DonutCardComponent implements OnInit { + ngOnInit(): void { + } +} diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 463a81b..cd0e6d7 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -6,11 +6,21 @@ import { Donut } from "../../models/donut.model"; selector: 'app-donut-list', template: `
- // pipe to json - {{ donut | json }} +
+
+ +
+

{{ donut.name }} +

+

{{ donut.price }} +

`, @@ -29,7 +39,7 @@ export class DonutListComponent implements OnInit { { id: 'xy12yr', name: 'Just Chocolate', - icon: 'jus-chocolate', + icon: 'just-chocolate', price: 119, description: 'For the pure chocoholic.', }, From 9845b7c254a8a16fcd0d4a2d95dbbbd8da66cdfc Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 20:07:39 +0200 Subject: [PATCH 06/66] Pass State to Dumb Components via @Input --- .../donut-card/donut-card.component.ts | 26 ++++++++++++++----- .../donut-list/donut-list.component.ts | 25 +++--------------- src/app/app.component.ts | 2 +- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index a4f61ed..287cdbc 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -1,16 +1,28 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, Input} from '@angular/core'; +import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-card', template: ` -

- donut-card works! -

+
+ +
+
+

+ {{ donut.name }} +

+

+ {{ donut.price }} +

+
`, styles: [ ] }) -export class DonutCardComponent implements OnInit { - ngOnInit(): void { - } +export class DonutCardComponent { + @Input() donut!: Donut; } diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index cd0e6d7..c431191 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -3,25 +3,12 @@ import {Component, OnInit} from '@angular/core'; import { Donut } from "../../models/donut.model"; @Component({ - selector: 'app-donut-list', + selector: 'donut-list', template: `
-
-
- -
-
-

- {{ donut.name }} -

-

- {{ donut.price }} -

-
+
+
+
`, styles: [ @@ -29,11 +16,8 @@ import { Donut } from "../../models/donut.model"; }) export class DonutListComponent implements OnInit { // Declaratie hier maar vullen in ngOnInit() - donut!: Donut; donuts!: Donut[]; - constructor() {} - ngOnInit(): void { this.donuts = [ { @@ -58,6 +42,5 @@ export class DonutListComponent implements OnInit { description: 'Chocolate drizzled with caramel', } ] - this.donut = this.donuts[0]; } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8de62d4..ba4bd61 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,7 +5,7 @@ import * as events from "events"; selector: 'app-root', template: `
- +
`, styles: [ ` From a798766aae3f7c51efa83f1d264e1de65ea03b15 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 21:07:40 +0200 Subject: [PATCH 07/66] Scoped Styles in Components --- .../donut-card/donut-card.component.ts | 43 +++++++++++++++---- src/app/app.component.ts | 23 ++++++++-- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 287cdbc..31e1b62 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -10,17 +10,44 @@ import {Donut} from "../../models/donut.model"; [alt]="donut.name" class="donut-card-icon" /> +
+

+ {{ donut.name }} +

+

+ {{ donut.price }} +

+
-
-

- {{ donut.name }} -

-

- {{ donut.price }} -

-
+ `, styles: [ + ` + .donut-card { // verwijst naar
+ display: flex; + align-items: center; + background: #f7f7f7; + border-radius: 5px; + margin-bottom: 5px; + padding: 5px 15px; + transition: transform 0.2s ease-in-out; + &:hover { + transform: translateY(-3px); + } + &-name { // nieuw in "style": "scss" Hierdoor hoef je niet de volledige class op te geven en verwijst naar

+ // "scss" wordt uitgesproken als sass + font-size: 16px; + } + &-price { // verwijst naar

+ font-size: 14px; + color: #c14583; + } + &-icon { // verwijst naar

+ width: 50px; + margin-right: 10px; + } + } + `, ] }) export class DonutCardComponent { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ba4bd61..692f735 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,15 +5,30 @@ import * as events from "events"; selector: 'app-root', template: `

+
+ +
`, styles: [ ` .app { - margin-top: 50px; - font-size: 22px; - color: #fff; - text-align: center; + background: #fff; + border-radius: 8px; + max-width: 400px; + width: 94%; + margin: 25px auto; + padding: 25px; + border: 4px solid #ef9fc7; + } + .header { + display: flex; + justify-content: center; + margin-bottom: 25px; + } + .logo { + width: 100px; + height: 88px; } `, ], From 2719925e9a0641ac338a111eca0642e72d14f1b8 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 21:21:05 +0200 Subject: [PATCH 08/66] Style a Host Element --- src/app/admin/components/donut-card/donut-card.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 31e1b62..0f936c2 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -4,7 +4,6 @@ import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-card', template: ` -
-
`, styles: [ ` - .donut-card { // verwijst naar
+ :host { display: flex; align-items: center; background: #f7f7f7; @@ -34,6 +32,8 @@ import {Donut} from "../../models/donut.model"; &:hover { transform: translateY(-3px); } + } + .donut-card { // verwijst naar
&-name { // nieuw in "style": "scss" Hierdoor hoef je niet de volledige class op te geven en verwijst naar

// "scss" wordt uitgesproken als sass font-size: 16px; From 7c38f4f15d043ff6a26a2f5702925af558f283c1 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 26 Oct 2023 21:38:41 +0200 Subject: [PATCH 09/66] View Encapsulation: Shadow DOM and Emulated --- .../components/donut-card/donut-card.component.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 0f936c2..a1d61c0 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -1,8 +1,21 @@ -import {Component, Input} from '@angular/core'; +import {Component, Input, ViewEncapsulation} from '@angular/core'; import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-card', + // encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt + encapsulation: ViewEncapsulation.ShadowDom, // Niet van styles.scss maar van styles: [ .app { margin: 25px auto; + // styles: [ + // ` + // .app { + // background: #fff; + // border-radius: 8px; + // max-width: 400px; + // width: 94%; + // margin: 25px auto; + // padding: 25px; + // border: 4px solid #ef9fc7; + // } template: ` Date: Fri, 27 Oct 2023 06:00:50 +0200 Subject: [PATCH 10/66] Set Inline Styles with Style Bindings --- .../donut-card/donut-card.component.ts | 21 +++++-------------- .../donut-list/donut-list.component.ts | 1 + src/app/admin/models/donut.model.ts | 1 + 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index a1d61c0..ffd57bf 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -3,20 +3,10 @@ import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-card', - // encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt - encapsulation: ViewEncapsulation.ShadowDom, // Niet van styles.scss maar van styles: [ .app { margin: 25px auto; - // styles: [ - // ` - // .app { - // background: #fff; - // border-radius: 8px; - // max-width: 400px; - // width: 94%; - // margin: 25px auto; - // padding: 25px; - // border: 4px solid #ef9fc7; - // } + encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt template: ` +

+
`, styles: [ ` - :host { + .donut-card { display: flex; align-items: center; background: #f7f7f7; @@ -45,8 +36,6 @@ import {Donut} from "../../models/donut.model"; &:hover { transform: translateY(-3px); } - } - .donut-card { // verwijst naar
&-name { // nieuw in "style": "scss" Hierdoor hoef je niet de volledige class op te geven en verwijst naar

// "scss" wordt uitgesproken als sass font-size: 16px; diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index c431191..3502783 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -25,6 +25,7 @@ export class DonutListComponent implements OnInit { name: 'Just Chocolate', icon: 'just-chocolate', price: 119, + promo: true, description: 'For the pure chocoholic.', }, { diff --git a/src/app/admin/models/donut.model.ts b/src/app/admin/models/donut.model.ts index 6100bae..1544e55 100644 --- a/src/app/admin/models/donut.model.ts +++ b/src/app/admin/models/donut.model.ts @@ -3,5 +3,6 @@ export interface Donut { name: string; icon: string; price: number; + promo?: boolean; description: string; } From 3f0b10a22b1f3ead06c350a004b39ae403881437 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Fri, 27 Oct 2023 06:14:31 +0200 Subject: [PATCH 11/66] Complex Inline Styles with NgStyle --- .../donut-card/donut-card.component.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index ffd57bf..21bf1d5 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -5,8 +5,14 @@ import {Donut} from "../../models/donut.model"; selector: 'donut-card', encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt template: ` -

+
+ - // "scss" wordt uitgesproken als sass - font-size: 16px; + &-name { + //font-size: 16px; } - &-price { // verwijst naar

- font-size: 14px; + &-price { + //font-size: 14px; color: #c14583; } - &-icon { // verwijst naar

+ &-icon { width: 50px; margin-right: 10px; } From c482fd94cb190c01abf024d81928d217f6c2a0e5 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Fri, 27 Oct 2023 06:24:28 +0200 Subject: [PATCH 12/66] Set Classes with Class Bindings --- .../components/donut-card/donut-card.component.ts | 15 ++++++--------- .../containers/donut-list/donut-list.component.ts | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 21bf1d5..97f2219 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -5,14 +5,8 @@ import {Donut} from "../../models/donut.model"; selector: 'donut-card', encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt template: ` -

- Date: Fri, 27 Oct 2023 06:37:41 +0200 Subject: [PATCH 13/66] Complex Classes with NgClass --- .../components/donut-card/donut-card.component.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 97f2219..ee1844b 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -5,8 +5,17 @@ import {Donut} from "../../models/donut.model"; selector: 'donut-card', encapsulation: ViewEncapsulation.Emulated, // Is de default dat wil zeggen dat nu de css van styles.scss genomen wordt template: ` -
+
+ Date: Fri, 27 Oct 2023 06:52:47 +0200 Subject: [PATCH 14/66] Use a Pipe to Format Currency --- .../components/donut-card/donut-card.component.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index ee1844b..c331fa8 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -8,14 +8,9 @@ import {Donut} from "../../models/donut.model";
-

- {{ donut.price }} + {{ donut.price / 100 | currency }} + {{ donut.price / 100 | currency: 'USD': 'code' }} + {{ donut.price / 100 | currency: 'EUR': 'symbol' }}

+ `, styles: [ From 246bb733102ebe5f755288196adbc8afbe7108cb Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 29 Oct 2023 16:22:14 +0100 Subject: [PATCH 15/66] Use NgIf for Conditional Rendering --- .../donut-card/donut-card.component.ts | 6 --- .../donut-list/donut-list.component.ts | 52 ++++++++++--------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index c331fa8..9bf8aa8 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -22,15 +22,9 @@ import {Donut} from "../../models/donut.model";

{{ donut.price / 100 | currency }} - {{ donut.price / 100 | currency: 'USD': 'code' }} - {{ donut.price / 100 | currency: 'EUR': 'symbol' }}

- - `, styles: [ ` diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index dd62bc2..1207e6e 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -6,9 +6,11 @@ import { Donut } from "../../models/donut.model"; selector: 'donut-list', template: `
-
-
-
+
+ + + +
`, styles: [ @@ -20,28 +22,28 @@ export class DonutListComponent implements OnInit { ngOnInit(): void { this.donuts = [ - { - id: 'xy12yr', - name: 'Just Chocolate', - icon: 'just-chocolate', - price: 119, - description: 'For the pure chocoholic.', - }, - { - id: 'zy19yr', - name: 'Glazed Fudge', - icon: 'glazed-fudge', - price: 129, - promo: true, - description: 'Sticky perfection.', - }, - { - id: 'qy19ya', - name: 'Caramel Swirl', - icon: 'caramel-swirl', - price: 129, - description: 'Chocolate drizzled with caramel', - } + // { + // id: 'xy12yr', + // name: 'Just Chocolate', + // icon: 'just-chocolate', + // price: 119, + // description: 'For the pure chocoholic.', + // }, + // { + // id: 'zy19yr', + // name: 'Glazed Fudge', + // icon: 'glazed-fudge', + // price: 129, + // promo: true, + // description: 'Sticky perfection.', + // }, + // { + // id: 'qy19ya', + // name: 'Caramel Swirl', + // icon: 'caramel-swirl', + // price: 129, + // description: 'Chocolate drizzled with caramel', + // } ] } } From e78b14f3d8959648959d24fb4c13a20993fdbfdd Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 29 Oct 2023 18:42:02 +0100 Subject: [PATCH 16/66] Use the NgIf, Else and Then Syntax --- .../donut-list/donut-list.component.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 1207e6e..62845fa 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -5,13 +5,19 @@ import { Donut } from "../../models/donut.model"; @Component({ selector: 'donut-list', template: ` -
-
- - - -
+
+ +
+ + + + + + + +

No Donust here..

+
`, styles: [ ] From 9562c7b5dc4bb18a64d93c4fc040c680d11c4809 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 30 Oct 2023 22:21:16 +0100 Subject: [PATCH 17/66] NgIf Syntax with vs --- .../donut-list/donut-list.component.ts | 83 +++++++++++-------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 62845fa..ac1be1a 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -5,19 +5,34 @@ import { Donut } from "../../models/donut.model"; @Component({ selector: 'donut-list', template: ` -
- - -
+ // ng-container vs ng-template: + // Een ng-container wordt altijd gerendered + // terwijl een ng-template pas gerenderd wordt op basis van een voorwaarde + // Volgende zijn gelijk +
+ + + + + - - - - - - -

No Donust here..

-
+ + + + + + + // Volgende wordt niet gerenderd + + + + + + + +

No Donust here..

+
+
`, styles: [ ] @@ -28,28 +43,28 @@ export class DonutListComponent implements OnInit { ngOnInit(): void { this.donuts = [ - // { - // id: 'xy12yr', - // name: 'Just Chocolate', - // icon: 'just-chocolate', - // price: 119, - // description: 'For the pure chocoholic.', - // }, - // { - // id: 'zy19yr', - // name: 'Glazed Fudge', - // icon: 'glazed-fudge', - // price: 129, - // promo: true, - // description: 'Sticky perfection.', - // }, - // { - // id: 'qy19ya', - // name: 'Caramel Swirl', - // icon: 'caramel-swirl', - // price: 129, - // description: 'Chocolate drizzled with caramel', - // } + { + id: 'xy12yr', + name: 'Just Chocolate', + icon: 'just-chocolate', + price: 119, + description: 'For the pure chocoholic.', + }, + { + id: 'zy19yr', + name: 'Glazed Fudge', + icon: 'glazed-fudge', + price: 129, + promo: true, + description: 'Sticky perfection.', + }, + { + id: 'qy19ya', + name: 'Caramel Swirl', + icon: 'caramel-swirl', + price: 129, + description: 'Chocolate drizzled with caramel', + } ] } } From 739e4d33ae9fd244a3f21d68c17efbe16273556a Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 30 Oct 2023 22:29:17 +0100 Subject: [PATCH 18/66] NgFor and Iterating Collections --- .../donut-list/donut-list.component.ts | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index ac1be1a..08f23c3 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -5,34 +5,18 @@ import { Donut } from "../../models/donut.model"; @Component({ selector: 'donut-list', template: ` - // ng-container vs ng-template: - // Een ng-container wordt altijd gerendered - // terwijl een ng-template pas gerenderd wordt op basis van een voorwaarde - // Volgende zijn gelijk -
- - - - - +
+ + + + - - - - - - - // Volgende wordt niet gerenderd - - - - - - - -

No Donust here..

-
-
+ +

No Donust here..

+
+
`, styles: [ ] From 1ef48c581112e138f58aa8985bc5073ac33436a3 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 30 Oct 2023 22:41:47 +0100 Subject: [PATCH 19/66] Improve NgFor Performance with TrackBy --- .../admin/containers/donut-list/donut-list.component.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 08f23c3..5c9d255 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -8,7 +8,7 @@ import { Donut } from "../../models/donut.model";
@@ -51,4 +51,9 @@ export class DonutListComponent implements OnInit { } ] } + + trackById(index: number, value: Donut) { + return value.id; + + } } From b249923aecc87427c37cb9b702e11e3758c9d178 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 5 Nov 2023 17:49:20 +0100 Subject: [PATCH 20/66] Access NgFor Index, Odd and Even Variables --- .../donut-list/donut-list.component.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 5c9d255..1d54a2c 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -8,9 +8,25 @@ import { Donut } from "../../models/donut.model";
+ +
+ {{ i + 1 }} + {{ o }} + {{ e }} +
+ +
From da4b909ce92c9a690208aa6c81656f4668d1a29a Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 5 Nov 2023 17:51:26 +0100 Subject: [PATCH 21/66] undo Access NgFor Index, Odd and Even Variables --- .../containers/donut-list/donut-list.component.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 1d54a2c..399096f 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -12,21 +12,6 @@ import { Donut } from "../../models/donut.model"; [donut]="donut"> -
- {{ i + 1 }} - {{ o }} - {{ e }} -
- - From c6d7a5830ffae8e9f37d87988428ac3e4df05dc6 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 5 Nov 2023 18:02:51 +0100 Subject: [PATCH 22/66] Advanced NgFor Syntax with --- src/app/admin/containers/donut-list/donut-list.component.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 399096f..efc10c7 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -11,7 +11,11 @@ import { Donut } from "../../models/donut.model"; *ngFor="let donut of donuts; trackBy: trackById;" [donut]="donut"> - + // Bovenste *ngIf (astrix staat voor template, angular zet dit achterliggend om naar: + + + {{ i }} + From 45a197793f588157c97966f04df129fe0fb64a44 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 5 Nov 2023 18:34:50 +0100 Subject: [PATCH 23/66] Use NgSwitch for Case Rendering --- .../donut-card/donut-card.component.ts | 16 ++++++++++++++ .../donut-list/donut-list.component.ts | 22 ++++++++++++++----- src/app/admin/models/donut.model.ts | 2 +- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 9bf8aa8..5df6cd0 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -19,6 +19,14 @@ import {Donut} from "../../models/donut.model";

{{ donut.name }} + + NEW + LIMITED + + Nothing special... + +

{{ donut.price / 100 | currency }} @@ -42,6 +50,14 @@ import {Donut} from "../../models/donut.model"; &-name { font-size: 16px; } + &-label { + border: 1px solid #c14583; + border-radius: 4px; + padding: 0 4px; + margin-left: 5px; + font-size: 12px; + color: #c14583; + } &-price { font-size: 14px; color: #c14583; diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index efc10c7..40f71d2 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -11,11 +11,6 @@ import { Donut } from "../../models/donut.model"; *ngFor="let donut of donuts; trackBy: trackById;" [donut]="donut"> - // Bovenste *ngIf (astrix staat voor template, angular zet dit achterliggend om naar: - - - {{ i }} - @@ -37,6 +32,7 @@ export class DonutListComponent implements OnInit { name: 'Just Chocolate', icon: 'just-chocolate', price: 119, + promo: 'limited', description: 'For the pure chocoholic.', }, { @@ -44,7 +40,7 @@ export class DonutListComponent implements OnInit { name: 'Glazed Fudge', icon: 'glazed-fudge', price: 129, - promo: true, + promo: 'new', description: 'Sticky perfection.', }, { @@ -53,6 +49,20 @@ export class DonutListComponent implements OnInit { icon: 'caramel-swirl', price: 129, description: 'Chocolate drizzled with caramel', + }, + { + id: '2dfe5', + name: 'Sour Supreme', + icon: 'sour-supreme', + price: 139, + description: 'For the sour advocate.', + }, + { + id: 'a6rfg', + name: 'Zesty Lemon', + icon: 'zesty-lemon', + price: 129, + description: 'Delicious luscious lemon.', } ] } diff --git a/src/app/admin/models/donut.model.ts b/src/app/admin/models/donut.model.ts index 1544e55..4f2d975 100644 --- a/src/app/admin/models/donut.model.ts +++ b/src/app/admin/models/donut.model.ts @@ -3,6 +3,6 @@ export interface Donut { name: string; icon: string; price: number; - promo?: boolean; + promo?: 'new' | 'limited'; description: string; } From c8733e2bc4edb0e5a523ce5f894694cfbd71b1ae Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Sun, 5 Nov 2023 18:46:15 +0100 Subject: [PATCH 24/66] Advanced NgSwitch Syntax with --- .../admin/components/donut-card/donut-card.component.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app/admin/components/donut-card/donut-card.component.ts b/src/app/admin/components/donut-card/donut-card.component.ts index 5df6cd0..97e7c7f 100644 --- a/src/app/admin/components/donut-card/donut-card.component.ts +++ b/src/app/admin/components/donut-card/donut-card.component.ts @@ -20,11 +20,10 @@ import {Donut} from "../../models/donut.model";

{{ donut.name }} - NEW - LIMITED - - Nothing special... + + NEW + LIMITED + Nothing special...

From d91e66571d79172dcdc4bc72cb0be71f5753e442 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 11:52:55 +0100 Subject: [PATCH 25/66] Create a Form Container and Dumb Component --- src/app/admin/admin.module.ts | 14 ++++++++++---- .../components/donut-form/donut-form.component.ts | 15 +++++++++++++++ .../donut-single/donut-single.component.ts | 15 +++++++++++++++ src/app/app.component.ts | 2 +- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/app/admin/components/donut-form/donut-form.component.ts create mode 100644 src/app/admin/containers/donut-single/donut-single.component.ts diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 4250f7b..db046c3 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -1,17 +1,23 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { DonutListComponent } from './containers/donut-list/donut-list.component'; -import { DonutCardComponent } from './components/donut-card/donut-card.component'; +// containers +import { DonutListComponent } from './containers/donut-list/donut-list.component'; +import { DonutSingleComponent } from './containers/donut-single/donut-single.component'; +// components +import { DonutCardComponent } from './components/donut-card/donut-card.component'; +import { DonutFormComponent } from './components/donut-form/donut-form.component'; @NgModule({ declarations: [ DonutListComponent, - DonutCardComponent + DonutSingleComponent, + DonutCardComponent, + DonutFormComponent, ], exports: [ - DonutListComponent + DonutListComponent, DonutSingleComponent ], imports: [ CommonModule diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts new file mode 100644 index 0000000..3185409 --- /dev/null +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-donut-form', + template: ` +

+ donut-form works! +

+ `, + styles: [ + ] +}) +export class DonutFormComponent { + +} diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts new file mode 100644 index 0000000..11b6bad --- /dev/null +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'donut-single', + template: ` +

+ donut-single works! +

+ `, + styles: [ + ] +}) +export class DonutSingleComponent { + +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 692f735..4d557b1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -8,7 +8,7 @@ import * as events from "events";
- +
`, styles: [ ` From 8f07f3b00897becaab7dc9eab2f689079a095b78 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 15:22:45 +0100 Subject: [PATCH 26/66] Binding with ngModel --- src/app/admin/admin.module.ts | 5 ++-- .../donut-form/donut-form.component.ts | 23 +++++++++++++------ src/app/app.component.ts | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index db046c3..b9148ec 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import {FormsModule} from "@angular/forms"; // containers import { DonutListComponent } from './containers/donut-list/donut-list.component'; @@ -17,10 +18,10 @@ import { DonutFormComponent } from './components/donut-form/donut-form.component DonutFormComponent, ], exports: [ - DonutListComponent, DonutSingleComponent + DonutListComponent, DonutSingleComponent, DonutFormComponent ], imports: [ - CommonModule + CommonModule, FormsModule ] }) export class AdminModule { } diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index 3185409..a956af1 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -1,15 +1,24 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; @Component({ - selector: 'app-donut-form', + selector: 'donut-form', template: ` -

- donut-form works! -

+
+ +
 {{ form.value | json}} 
+
`, styles: [ ] }) -export class DonutFormComponent { - +export class DonutFormComponent implements OnInit { + constructor() { + } + ngOnInit(): void { + } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 4d557b1..e9153dd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -8,7 +8,7 @@ import * as events from "events";
- +
`, styles: [ ` From 7418226a41f904a68a873094d2dbc0e39e96483c Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 15:49:36 +0100 Subject: [PATCH 27/66] Radio Button Binding with NgModel --- .../donut-form/donut-form.component.ts | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index a956af1..49f0bae 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -7,13 +7,53 @@ import {Component, OnInit} from '@angular/core'; + + -
 {{ form.value | json}} 
+ +
+

Promo:

+ + + +
+ +
 {{ form.value | json }} 
`, styles: [ + ` + .donut-form { + &-radios { + display: flex; + align-content: center; + &-label { + margin-right: 10px; + } + label { + display: flex; + align-items: center; + span { + color: #444; + margin-bottom: 0; + } + } + } + } + ` ] }) export class DonutFormComponent implements OnInit { From 63d2709a90bd2749bd961eacd0355220eed9cad1 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 16:08:23 +0100 Subject: [PATCH 28/66] + +
+ +
 {{ form.value | json }} 
`, From 45ebc0f7ba191688726363110a37a166d0762a79 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 16:27:31 +0100 Subject: [PATCH 30/66] Add Validation Constraints and Form Status --- .../donut-form/donut-form.component.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index dc6e8cc..bd04228 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -6,16 +6,12 @@ import {Component, OnInit} from '@angular/core';
-
 {{ form.value | json }} 
+
 {{ form.form.status | json }} 
`, styles: [ From d8edf3d7510d91ac0d646c22f5ac7ce480161cf8 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Mon, 18 Dec 2023 16:43:11 +0100 Subject: [PATCH 31/66] NgModel Template Refs and Validation States --- .../admin/components/donut-form/donut-form.component.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index bd04228..2c7aa2b 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -6,7 +6,13 @@ import {Component, OnInit} from '@angular/core';
- +
 {{ form.value | json }} 
`, @@ -111,6 +121,8 @@ export class DonutFormComponent { handleSubmit(form: NgForm) { if (form.valid) { console.log(form.value) + }else { + form.form.markAllAsTouched() } } } From b63fe0e2db8092252e6269c2cf6917932f3994ce Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Tue, 19 Dec 2023 13:09:46 +0100 Subject: [PATCH 36/66] Control NgModel Writes with ngModelOptions --- src/app/admin/components/donut-form/donut-form.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index 24f9721..1a9a541 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -14,6 +14,7 @@ import {NgForm} from "@angular/forms"; required minlength="5" ngModel + [ngModelOptions]="{ updateOn: 'blur' }" #name="ngModel" /> From 3ac177e009efdebd7e60bbda3fd7ccfebf569c3c Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Tue, 19 Dec 2023 13:17:16 +0100 Subject: [PATCH 37/66] Trigger a Form State and Validation Reset --- src/app/admin/components/donut-form/donut-form.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index 1a9a541..a0dbd43 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -74,8 +74,10 @@ import {NgForm} from "@angular/forms"; - -
 {{ form.value | json }} 
+ + + +
 {{ form.value | json }} 
`, styles: [ From 0a041f080d9640619f084253cf82e49b12c00766 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Tue, 19 Dec 2023 13:23:47 +0100 Subject: [PATCH 38/66] Show Visual Feedback on Form Submission --- .../admin/components/donut-form/donut-form.component.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index a0dbd43..e89fd65 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -77,6 +77,10 @@ import {NgForm} from "@angular/forms"; +
+ Working... +
+
 {{ form.value | json }} 
`, @@ -98,6 +102,11 @@ import {NgForm} from "@angular/forms"; } } } + &-working { + font-size: 12px; + font-style: italic; + margin: 10px 0; + } &-error { font-size: 12px; color: #e66262; From 09a039e730617c0855054da0dbcbf82f3e662789 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Tue, 19 Dec 2023 13:46:07 +0100 Subject: [PATCH 39/66] Emit Form Payload to Smart Container via @Ou --- .../donut-form/donut-form.component.ts | 10 ++++++---- .../donut-single/donut-single.component.ts | 16 +++++++++++----- src/app/app.component.ts | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index e89fd65..8e08ddb 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -1,5 +1,6 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, EventEmitter, Output} from '@angular/core'; import {NgForm} from "@angular/forms"; +import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-form', @@ -117,6 +118,8 @@ import {NgForm} from "@angular/forms"; }) export class DonutFormComponent { + @Output() create = new EventEmitter() + icons: string[] = [ 'caramel-swirl', 'glazed-fudge', @@ -127,12 +130,11 @@ export class DonutFormComponent { 'zesty-lemon', ] - constructor() { - } + constructor() {} handleSubmit(form: NgForm) { if (form.valid) { - console.log(form.value) + this.create.emit(form.value) }else { form.form.markAllAsTouched() } diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index 11b6bad..7f09d70 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -1,15 +1,21 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; +import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-single', template: ` -

- donut-single works! -

+
+ +
`, styles: [ ] }) -export class DonutSingleComponent { +export class DonutSingleComponent implements OnInit { + constructor() {} + ngOnInit(): void {} + onCreate(donut: Donut) { + console.log('onCreate', donut) + } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index e9153dd..4d557b1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -8,7 +8,7 @@ import * as events from "events";
- +
`, styles: [ ` From 6cd5fe4cf3cf3c406f9562638a09c7fef8879e69 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Tue, 19 Dec 2023 14:01:34 +0100 Subject: [PATCH 40/66] One-Way Data Binding to NgModel --- .../donut-form/donut-form.component.ts | 18 ++++++++++-------- .../donut-single/donut-single.component.ts | 16 ++++++++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index 8e08ddb..d0a1971 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Output} from '@angular/core'; +import {Component, Input, Output, EventEmitter} from '@angular/core'; import {NgForm} from "@angular/forms"; import {Donut} from "../../models/donut.model"; @@ -14,7 +14,7 @@ import {Donut} from "../../models/donut.model"; class="input" required minlength="5" - ngModel + [ngModel]="donut.name" [ngModelOptions]="{ updateOn: 'blur' }" #name="ngModel" /> @@ -26,7 +26,7 @@ import {Donut} from "../../models/donut.model";
@@ -67,7 +67,7 @@ import {Donut} from "../../models/donut.model"; name="description" class="input input--textarea" required - ngModel + [ngModel]="donut.description" #description="ngModel" > @@ -82,6 +82,7 @@ import {Donut} from "../../models/donut.model"; Working...
+
 {{ donut | json }} 
 {{ form.value | json }} 
`, @@ -118,6 +119,7 @@ import {Donut} from "../../models/donut.model"; }) export class DonutFormComponent { + @Input() donut!: Donut; @Output() create = new EventEmitter() icons: string[] = [ diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index 7f09d70..cb3a501 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -5,15 +5,27 @@ import {Donut} from "../../models/donut.model"; selector: 'donut-single', template: `
- +
`, styles: [ ] }) export class DonutSingleComponent implements OnInit { + + donut!: Donut; + constructor() {} - ngOnInit(): void {} + ngOnInit(): void { + this.donut = { + id: 'xy12yr', + name: 'Just Chocolate', + icon: 'just-chocolate', + price: 119, + promo: 'limited', + description: 'For the pure chocoholic.', + }; + } onCreate(donut: Donut) { console.log('onCreate', donut) From 63a31c4aaf9d7fdafe0452805ce2026583679fed Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 20 Dec 2023 15:28:39 +0100 Subject: [PATCH 41/66] Create an @Injectable Service --- src/app/admin/services/donut.service.spec.ts | 16 ++++++++++++++++ src/app/admin/services/donut.service.ts | 9 +++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/app/admin/services/donut.service.spec.ts create mode 100644 src/app/admin/services/donut.service.ts diff --git a/src/app/admin/services/donut.service.spec.ts b/src/app/admin/services/donut.service.spec.ts new file mode 100644 index 0000000..3e1e36f --- /dev/null +++ b/src/app/admin/services/donut.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DonutService } from './donut.service'; + +describe('DonutService', () => { + let service: DonutService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DonutService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/admin/services/donut.service.ts b/src/app/admin/services/donut.service.ts new file mode 100644 index 0000000..c76599f --- /dev/null +++ b/src/app/admin/services/donut.service.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class DonutService { + + constructor() { } +} From 5555e3d4f9d4f4a6245b7ab8220b6a60e8f9056d Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 20 Dec 2023 15:45:38 +0100 Subject: [PATCH 42/66] Share State in Components via Services --- .../donut-list/donut-list.component.ts | 42 ++----------------- .../donut-single/donut-single.component.ts | 14 +++---- src/app/admin/models/donut.model.ts | 2 +- src/app/admin/services/donut.service.ts | 41 +++++++++++++++++- 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index 40f71d2..e2a7079 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -1,6 +1,7 @@ import {Component, OnInit} from '@angular/core'; import { Donut } from "../../models/donut.model"; +import {DonutService} from "../../services/donut.service"; @Component({ selector: 'donut-list', @@ -25,46 +26,9 @@ export class DonutListComponent implements OnInit { // Declaratie hier maar vullen in ngOnInit() donuts!: Donut[]; + constructor(private donutService: DonutService) {} ngOnInit(): void { - this.donuts = [ - { - id: 'xy12yr', - name: 'Just Chocolate', - icon: 'just-chocolate', - price: 119, - promo: 'limited', - description: 'For the pure chocoholic.', - }, - { - id: 'zy19yr', - name: 'Glazed Fudge', - icon: 'glazed-fudge', - price: 129, - promo: 'new', - description: 'Sticky perfection.', - }, - { - id: 'qy19ya', - name: 'Caramel Swirl', - icon: 'caramel-swirl', - price: 129, - description: 'Chocolate drizzled with caramel', - }, - { - id: '2dfe5', - name: 'Sour Supreme', - icon: 'sour-supreme', - price: 139, - description: 'For the sour advocate.', - }, - { - id: 'a6rfg', - name: 'Zesty Lemon', - icon: 'zesty-lemon', - price: 129, - description: 'Delicious luscious lemon.', - } - ] + this.donuts = this.donutService.donuts; } trackById(index: number, value: Donut) { diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index cb3a501..54bef78 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {Donut} from "../../models/donut.model"; +import {DonutService} from "../../services/donut.service"; @Component({ selector: 'donut-single', @@ -15,16 +16,11 @@ export class DonutSingleComponent implements OnInit { donut!: Donut; - constructor() {} + constructor(private donutService: DonutService) {} ngOnInit(): void { - this.donut = { - id: 'xy12yr', - name: 'Just Chocolate', - icon: 'just-chocolate', - price: 119, - promo: 'limited', - description: 'For the pure chocoholic.', - }; + let id = 'xy12yr'; + this.donut = this.donutService.donuts.find((donut:Donut) => donut.id === id) + || {name: '', icon: '', price: 0, description: ''}; } onCreate(donut: Donut) { diff --git a/src/app/admin/models/donut.model.ts b/src/app/admin/models/donut.model.ts index 4f2d975..bce3e22 100644 --- a/src/app/admin/models/donut.model.ts +++ b/src/app/admin/models/donut.model.ts @@ -1,5 +1,5 @@ export interface Donut { - id: string; + id?: string; name: string; icon: string; price: number; diff --git a/src/app/admin/services/donut.service.ts b/src/app/admin/services/donut.service.ts index c76599f..3dcaead 100644 --- a/src/app/admin/services/donut.service.ts +++ b/src/app/admin/services/donut.service.ts @@ -1,9 +1,48 @@ import { Injectable } from '@angular/core'; +import {Donut} from "../models/donut.model"; @Injectable({ providedIn: 'root' }) export class DonutService { - + donuts: Donut[] = [ + { + id: 'xy12yr', + name: 'Just Chocolate', + icon: 'just-chocolate', + price: 119, + promo: 'limited', + description: 'For the pure chocoholic.', + }, + { + id: 'zy19yr', + name: 'Glazed Fudge', + icon: 'glazed-fudge', + price: 129, + promo: 'new', + description: 'Sticky perfection.', + }, + { + id: 'qy19ya', + name: 'Caramel Swirl', + icon: 'caramel-swirl', + price: 129, + description: 'Chocolate drizzled with caramel', + }, + { + id: '2dfe5', + name: 'Sour Supreme', + icon: 'sour-supreme', + price: 139, + description: 'For the sour advocate.', + }, + { + id: 'a6rfg', + name: 'Zesty Lemon', + icon: 'zesty-lemon', + price: 129, + description: 'Delicious luscious lemon.', + } + ]; constructor() { } } From f1b5b473159dfc8d5d09435cdf033ad9998bfeaf Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 20 Dec 2023 16:02:12 +0100 Subject: [PATCH 43/66] Class Methods as State Selectors --- .../containers/donut-list/donut-list.component.ts | 2 +- .../donut-single/donut-single.component.ts | 4 +--- src/app/admin/services/donut.service.ts | 14 +++++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/app/admin/containers/donut-list/donut-list.component.ts b/src/app/admin/containers/donut-list/donut-list.component.ts index e2a7079..c6a8308 100644 --- a/src/app/admin/containers/donut-list/donut-list.component.ts +++ b/src/app/admin/containers/donut-list/donut-list.component.ts @@ -28,7 +28,7 @@ export class DonutListComponent implements OnInit { constructor(private donutService: DonutService) {} ngOnInit(): void { - this.donuts = this.donutService.donuts; + this.donuts = this.donutService.read(); } trackById(index: number, value: Donut) { diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index 54bef78..afb2e6e 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -18,9 +18,7 @@ export class DonutSingleComponent implements OnInit { constructor(private donutService: DonutService) {} ngOnInit(): void { - let id = 'xy12yr'; - this.donut = this.donutService.donuts.find((donut:Donut) => donut.id === id) - || {name: '', icon: '', price: 0, description: ''}; + this.donut = this.donutService.readOne('qy19ya'); } onCreate(donut: Donut) { diff --git a/src/app/admin/services/donut.service.ts b/src/app/admin/services/donut.service.ts index 3dcaead..1ad1bc9 100644 --- a/src/app/admin/services/donut.service.ts +++ b/src/app/admin/services/donut.service.ts @@ -5,7 +5,7 @@ import {Donut} from "../models/donut.model"; providedIn: 'root' }) export class DonutService { - donuts: Donut[] = [ + private donuts: Donut[] = [ { id: 'xy12yr', name: 'Just Chocolate', @@ -45,4 +45,16 @@ export class DonutService { } ]; constructor() { } + + read() { + return this.donuts; + } + + readOne(id: string) { + const donut = this.read().find((donut: Donut) => donut.id === id); + if (donut) { + return donut; + } + return {name: '', icon: '', price: 0, description: ''}; + } } From 8d5a3ebfbd552f779f79b878d27bc63682590868 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 20 Dec 2023 16:14:31 +0100 Subject: [PATCH 44/66] Immutable State Creation --- src/app/admin/components/donut-form/donut-form.component.ts | 3 --- .../admin/containers/donut-single/donut-single.component.ts | 4 ++-- src/app/admin/services/donut.service.ts | 5 +++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index d0a1971..4c5d247 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -81,9 +81,6 @@ import {Donut} from "../../models/donut.model";
Working...
- -
 {{ donut | json }} 
-
 {{ form.value | json }} 
`, styles: [ diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index afb2e6e..9c17563 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -18,10 +18,10 @@ export class DonutSingleComponent implements OnInit { constructor(private donutService: DonutService) {} ngOnInit(): void { - this.donut = this.donutService.readOne('qy19ya'); + this.donut = this.donutService.readOne('xxx'); } onCreate(donut: Donut) { - console.log('onCreate', donut) + this.donutService.create(donut); } } diff --git a/src/app/admin/services/donut.service.ts b/src/app/admin/services/donut.service.ts index 1ad1bc9..941538a 100644 --- a/src/app/admin/services/donut.service.ts +++ b/src/app/admin/services/donut.service.ts @@ -57,4 +57,9 @@ export class DonutService { } return {name: '', icon: '', price: 0, description: ''}; } + + create(payload: Donut) { + this.donuts = [...this.donuts, payload] + console.log(this.donuts); + } } From c2c9b3e34747872b348f9904b8ace3c30a9492a0 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Wed, 20 Dec 2023 19:08:55 +0100 Subject: [PATCH 45/66] Immutable State Updates --- .../donut-form/donut-form.component.ts | 67 ++++++++++++------- .../donut-single/donut-single.component.ts | 23 ++++--- src/app/admin/services/donut.service.ts | 18 ++++- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/app/admin/components/donut-form/donut-form.component.ts b/src/app/admin/components/donut-form/donut-form.component.ts index 4c5d247..ed8a62e 100644 --- a/src/app/admin/components/donut-form/donut-form.component.ts +++ b/src/app/admin/components/donut-form/donut-form.component.ts @@ -1,11 +1,11 @@ -import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Component, EventEmitter, Input, Output} from '@angular/core'; import {NgForm} from "@angular/forms"; import {Donut} from "../../models/donut.model"; @Component({ selector: 'donut-form', template: ` -
+
- - - - - -
- Working... -
+ + + + + +
+ Working... +
Loading... @@ -128,6 +155,8 @@ import {Donut} from "../../models/donut.model"; export class DonutFormComponent { @Input() donut!: Donut; + @Input() isEdit!: boolean; + @Output() create = new EventEmitter() @Output() update = new EventEmitter() @Output() delete = new EventEmitter() diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index e685db7..e690532 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -9,6 +9,7 @@ import {ActivatedRoute} from "@angular/router";
(this.donut = donut)); + this.isEdit = this.route.snapshot.data['isEdit']; } onCreate(donut: Donut) { From 6d0cd08a09a3737eb144e3521120ca8cc4aae040 Mon Sep 17 00:00:00 2001 From: Kristof Kox Date: Thu, 28 Dec 2023 16:38:26 +0100 Subject: [PATCH 66/66] Programmatic Navigation with Router.navigate( --- db.json | 12 ++++++++++-- .../donut-single/donut-single.component.ts | 9 +++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/db.json b/db.json index 9044770..e36e314 100644 --- a/db.json +++ b/db.json @@ -4,8 +4,8 @@ "id": "xy12yr", "name": "Just Chocolate", "icon": "just-chocolate", - "price": 119, - "promo": "limited", + "price": 120, + "promo": "new", "description": "For the pure chocoholic." }, { @@ -37,6 +37,14 @@ "icon": "zesty-lemon", "price": 129, "description": "Delicious luscious lemon." + }, + { + "name": "teestfff", + "icon": "glazed-fudge", + "price": 3, + "promo": "limited", + "description": "qdsqsdf", + "id": "RF-n7_z" } ] } \ No newline at end of file diff --git a/src/app/admin/containers/donut-single/donut-single.component.ts b/src/app/admin/containers/donut-single/donut-single.component.ts index e690532..7135265 100644 --- a/src/app/admin/containers/donut-single/donut-single.component.ts +++ b/src/app/admin/containers/donut-single/donut-single.component.ts @@ -1,7 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {Donut} from "../../models/donut.model"; import {DonutService} from "../../services/donut.service"; -import {ActivatedRoute} from "@angular/router"; +import {ActivatedRoute, Router} from "@angular/router"; @Component({ selector: 'donut-single', @@ -25,6 +25,7 @@ export class DonutSingleComponent implements OnInit { constructor( private route: ActivatedRoute, + private router: Router, private donutService: DonutService, ) {} @@ -40,12 +41,12 @@ export class DonutSingleComponent implements OnInit { onCreate(donut: Donut) { this.donutService .create(donut) - .subscribe(() => console.log('Created successfully!')); + .subscribe((donut) => this.router.navigate(['admin', 'donuts', donut.id])); } onUpdate(donut: Donut) { this.donutService.update(donut).subscribe({ - next: () => console.log('Updated successfully!'), + next: () => this.router.navigate(['admin']), error: (err) => console.log('onUpdate error:', err), }); } @@ -53,6 +54,6 @@ export class DonutSingleComponent implements OnInit { onDelete(donut: Donut) { this.donutService .delete(donut) - .subscribe(()=> console.log('Deleted successfully!')); + .subscribe(()=> this.router.navigate(['admin'])); } }