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(), ); }); }