Content
View differences
Updated by Alexander Coles 15 days ago
27 27 Stimulus controllers reach into Angular's Angular's DI container through window.OpenProject.getPluginContext(). Each hand-rolls the Callers must know about RxJS, about opModalService.activeModalInstance$, about async context resolution resolution. The seam between Stimulus and its disconnect-before-resolve race guard differently (Symbol tokens, isConnected checks, unguarded awaits, RxJS from() chains) — or not Angular is a global window property with no adapter.
Extract a thin adapter at all.
A useServices Stimulus mixin (stimulus-use style) now owns the seam: controllers declare static services = \['halEvents'\], seam (e.g. AngularBridgeService) with named methods (closeActiveModal, openModal, getPathHelper, etc.) that hide RxJS, the mixin binds the services after connect, fires a servicesConnected() hook, async context, and guards all races centrally (pending resolutions never act on disconnected elements). this.services / this.pluginContext promises cover lazy event-handler use and the classes/injector escape hatch.
Angular's service graph. Controllers import the mixin, adapter, not the global.
When Angular is removed, change one mixin, adapter, not 27 controllers.
Extract a thin adapter
A useServices Stimulus mixin (stimulus-use style) now owns the seam: controllers declare static services = \['halEvents'\],