Content
View differences
Updated by Alexander Coles 8 days ago
27 Stimulus controllers reach into Angular's DI container through window.OpenProject.getPluginContext(). Each hand-rolls the async context resolution and its disconnect-before-resolve race guard differently (Symbol tokens, isConnected checks, unguarded awaits, RxJS from() chains) — or not at all.
A useServices Stimulus mixin (stimulus-use style) now owns the seam: controllers declare static services = \['halEvents'\], the mixin binds the services after connect, fires a servicesConnected() hook, 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.
Controllers import the mixin, not the global. When Angular is removed, change one mixin, not 27 controllers.
### Hints for QA
Dev-facing so no QA pass needed.
A useServices Stimulus mixin (stimulus-use style) now owns the seam: controllers declare static services = \['halEvents'\], the mixin binds the services after connect, fires a servicesConnected() hook, 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.
Controllers import the mixin, not the global. When Angular is removed, change one mixin, not 27 controllers.
### Hints for QA
Dev-facing so no QA pass needed.