Differenzansicht 14-directives
im Vergleich zu 13-pipes

← Zurück zur Ãœbersicht | Demo | Quelltext auf GitHub
src/app/books/book-details/book-details.component.html CHANGED
@@ -23,11 +23,13 @@
23
  [src]="book.thumbnailUrl"
24
  alt="Cover">
25
  <a class="button arrow-left" routerLink="..">Back to list</a>
26
- <button class="red" (click)="removeBook(book.isbn)">
27
- Remove book
28
- </button>
29
- <a class="button"
30
- [routerLink]="['/admin/edit', book.isbn]">
31
- Edit book
32
- </a>
 
 
33
  </div>
23
  [src]="book.thumbnailUrl"
24
  alt="Cover">
25
  <a class="button arrow-left" routerLink="..">Back to list</a>
26
+ <ng-container *bmLoggedinOnly>
27
+ <button class="red" bmConfirm="Remove book?" (confirm)="removeBook(book.isbn)">
28
+ Remove book
29
+ </button>
30
+ <a class="button"
31
+ [routerLink]="['/admin/edit', book.isbn]">
32
+ Edit book
33
+ </a>
34
+ </ng-container>
35
  </div>
src/app/books/book-details/book-details.component.ts CHANGED
@@ -24,10 +24,8 @@ export class BookDetailsComponent {
24
  }
25
 
26
  removeBook(isbn: string) {
27
- if (window.confirm('Remove book?')) {
28
- this.service.remove(isbn).subscribe(() => {
29
- this.router.navigateByUrl('/books');
30
- });
31
- }
32
  }
33
  }
24
  }
25
 
26
  removeBook(isbn: string) {
27
+ this.service.remove(isbn).subscribe(() => {
28
+ this.router.navigateByUrl('/books');
29
+ });
 
 
30
  }
31
  }
src/app/books/books.module.ts CHANGED
@@ -6,13 +6,17 @@ import { BookListComponent } from './book-list/book-list.component';
6
  import { BookListItemComponent } from './book-list-item/book-list-item.component';
7
  import { BookDetailsComponent } from './book-details/book-details.component';
8
  import { IsbnPipe } from './shared/isbn.pipe';
 
 
9
 
10
  @NgModule({
11
  declarations: [
12
  BookListComponent,
13
  BookListItemComponent,
14
  BookDetailsComponent,
15
- IsbnPipe
 
 
16
  ],
17
  imports: [
18
  CommonModule,
6
  import { BookListItemComponent } from './book-list-item/book-list-item.component';
7
  import { BookDetailsComponent } from './book-details/book-details.component';
8
  import { IsbnPipe } from './shared/isbn.pipe';
9
+ import { ConfirmDirective } from './shared/confirm.directive';
10
+ import { LoggedinOnlyDirective } from './shared/loggedin-only.directive';
11
 
12
  @NgModule({
13
  declarations: [
14
  BookListComponent,
15
  BookListItemComponent,
16
  BookDetailsComponent,
17
+ IsbnPipe,
18
+ ConfirmDirective,
19
+ LoggedinOnlyDirective
20
  ],
21
  imports: [
22
  CommonModule,
src/app/books/shared/confirm.directive.ts ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
2
+
3
+ @Directive({
4
+ selector: '[bmConfirm]',
5
+ standalone: false
6
+ })
7
+ export class ConfirmDirective {
8
+ @Input('bmConfirm') confirmText?: string;
9
+ @Output() confirm = new EventEmitter<void>();
10
+
11
+ @HostListener('click') onClick() {
12
+ if (window.confirm(this.confirmText)) {
13
+ this.confirm.emit();
14
+ }
15
+ }
16
+ }
src/app/books/shared/loggedin-only.directive.ts ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Directive, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+
4
+ import { AuthService } from '../../shared/auth.service';
5
+
6
+ @Directive({
7
+ selector: '[bmLoggedinOnly]',
8
+ standalone: false
9
+ })
10
+ export class LoggedinOnlyDirective implements OnDestroy {
11
+ private destroy$ = new Subject<void>();
12
+
13
+ constructor(
14
+ private template: TemplateRef<unknown>,
15
+ private viewContainer: ViewContainerRef,
16
+ private authService: AuthService
17
+ ) {
18
+ this.authService.isAuthenticated$.pipe(
19
+ takeUntil(this.destroy$)
20
+ ).subscribe(isAuthenticated => {
21
+ if (isAuthenticated) {
22
+ this.viewContainer.createEmbeddedView(this.template);
23
+ } else {
24
+ this.viewContainer.clear();
25
+ }
26
+ });
27
+ }
28
+
29
+ ngOnDestroy(): void {
30
+ this.destroy$.next();
31
+ }
32
+ }