diff --git a/apps/angular/33-decoupling-components/src/app/app.component.ts b/apps/angular/33-decoupling-components/src/app/app.component.ts
index 0d78f4d34..2dac01c22 100644
--- a/apps/angular/33-decoupling-components/src/app/app.component.ts
+++ b/apps/angular/33-decoupling-components/src/app/app.component.ts
@@ -1,12 +1,24 @@
import { BtnDisabledDirective } from '@angular-challenges/decoupling/brain';
import { BtnHelmetDirective } from '@angular-challenges/decoupling/helmet';
-import { Component } from '@angular/core';
+import { Component, signal } from '@angular/core';
@Component({
imports: [BtnDisabledDirective, BtnHelmetDirective],
selector: 'app-root',
template: `
-
+
`,
})
-export class AppComponent {}
+export class AppComponent {
+ readonly btnState = signal<'enabled' | 'disabled'>('disabled');
+
+ readonly onStateChange = (state: 'enabled' | 'disabled') => {
+ this.btnState.set(state);
+ };
+}
diff --git a/libs/decoupling/brain/src/lib/button-disabled.directive.ts b/libs/decoupling/brain/src/lib/button-disabled.directive.ts
index 71a5de9d2..a550f8198 100644
--- a/libs/decoupling/brain/src/lib/button-disabled.directive.ts
+++ b/libs/decoupling/brain/src/lib/button-disabled.directive.ts
@@ -1,6 +1,12 @@
/* eslint-disable @angular-eslint/directive-selector */
/* eslint-disable @angular-eslint/no-host-metadata-property */
-import { Directive, signal, WritableSignal } from '@angular/core';
+import {
+ Directive,
+ effect,
+ output,
+ signal,
+ WritableSignal,
+} from '@angular/core';
export type ButtonState = 'enabled' | 'disabled';
@@ -11,9 +17,19 @@ export type ButtonState = 'enabled' | 'disabled';
},
})
export class BtnDisabledDirective {
- state: WritableSignal = signal('enabled');
+ readonly state: WritableSignal = signal('enabled');
+ readonly stateChanged = output();
+
+ constructor() {
+ effect(this.onStateChange);
+ }
toggleState() {
this.state.set(this.state() === 'enabled' ? 'disabled' : 'enabled');
}
+
+ private onStateChange = () => {
+ const state = this.state();
+ this.stateChanged.emit(state);
+ };
}
diff --git a/libs/decoupling/helmet/src/lib/btn-style.directive.ts b/libs/decoupling/helmet/src/lib/btn-style.directive.ts
index f3adf6cd3..d92931375 100644
--- a/libs/decoupling/helmet/src/lib/btn-style.directive.ts
+++ b/libs/decoupling/helmet/src/lib/btn-style.directive.ts
@@ -1,12 +1,10 @@
-/* eslint-disable @angular-eslint/directive-selector */
-import { BtnDisabledDirective } from '@angular-challenges/decoupling/brain';
import {
Directive,
effect,
ElementRef,
inject,
+ input,
Renderer2,
- signal,
} from '@angular/core';
@Directive({
@@ -17,8 +15,7 @@ import {
},
})
export class BtnHelmetDirective {
- btnState = inject(BtnDisabledDirective, { self: true });
- public state = this.btnState?.state ?? signal('disabled').asReadonly();
+ readonly btnState = input<'enabled' | 'disabled'>('enabled');
private renderer = inject(Renderer2);
private element = inject(ElementRef);
@@ -26,7 +23,7 @@ export class BtnHelmetDirective {
this.renderer.setAttribute(
this.element.nativeElement,
'data-state',
- this.state(),
+ this.btnState(),
);
});
}