I'm trying to use signals and I'm wondering if the use case here is actually benefical from not using Signals and simply have a "normal" class member swiper?: Swiper
:
@Component({
selector: '[app-test]',
standalone: true,
imports: [CommonModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TestComponent implements AfterViewInit {
swiper = signal<Swiper|undefined>(undefined);
constructor(
private readonly cd: ChangeDetectorRef,
private readonly elementRef: ElementRef,
) { }
ngAfterViewInit(): void {
const swiper: unknown = this.elementRef.nativeElement.querySelector('swiper-container')?.swiper;
if (swiper instanceof Swiper) {
this.swiper.set(swiper);
this.cd.detectChanges();
}
}
slideTo(direction: 'prev'|'next'): void {
const swiper = this.swiper();
if (!swiper) return;
direction === 'prev' ? swiper.slidePrev() : swiper.slideNext();
}
}
And in the template:
<fieldset *ngIf="swiper() as swiper">
<button
type="button"
[attr.disabled]="swiper.activeIndex === 0 ? true : null"
(click)="slideTo('prev')"
>Prev</button>
<button
class="slider-navigation slider-navigation--next"
type="button"
[attr.disabled]="swiper.activeIndex === swiper.slides.length - 1 ? true : null"
(click)="slideTo('next')"
>Next</button>
</fieldset>
I do understand that I need to use this.cd.detectChanges();
since ngAfterViewInit
runs after Angular's change detection. But shouldn't Signales take care of it? It makes the code look exactly like not using Signals at all. Where's the benefit? Am I using it correctly here?
After some collective investigation, we found that the issue (in both versions of the code) is caused by the fact that the Change Detection cycle finishes after you set a signal.
That's why markForCheck()
doesn't work (signal already marks the views), and detectChanges()
works - another CD cycle is needed to check all the marked views.
Confirmed by Alex Rickabaugh.
Previous answer:
Here is your code on StackBlitz: https://stackblitz.com/edit/stackblitz-starters-1tnwze?file=src%2Fmain.ts
It works without a cd.detectChanges()
call.
It just prints one famous error to the console in dev mode ;)