Skip to content

@ngrx/signals/events: Provide Support for Scoped Events #4776

Open
@markostanimirovic

Description

@markostanimirovic

Which @ngrx/* package(s) are relevant/related to the feature request?

signals

Information

Currently, all events are dispatched using the globally provided Dispatcher. However, there are at least two scenarios where having scoped dispatchers and event handling would be beneficial:

  • Local state management: When multiple instances of the same component are initialized, each with its own store instance, events dispatched from a specific component instance should be handled exclusively by the store instance associated with that same component.
  • Microfrontends: Each microfrontend may require its own isolated dispatcher.

Solution

This functionality can be introduced by supporting a tree of dispatchers. Components or microfrontends that require a scoped dispatcher can use the provideDispatcher function. In the following example, events dispatched from MyComponent can only be handled by stores provided at the same level (MyComponent) or in its descendants.

import { event, provideDispatcher } from '@ngrx/signals/events';

const myEvent = event('myEvent');

@Component({
  providers: [
    provideDispatcher(),
    MyStore1,
    MyStore2,
  ],
})
export class MyComponent {
  readonly dispatcher = inject(Dispatcher);

  myMethod(): void {
    this.dispatcher.dispatch(myEvent());
  }
}

The dispatcher tree follows the same hierarchy as Angular's injector tree: events are visible to the level at which they are dispatched and to all descendants. For example, events dispatched to the root dispatcher are available to all nested dispatchers, but events dispatched to a child dispatcher are not visible to ancestors.

If needed, events can be explicitly dispatched to a parent or root dispatcher:

  myMethod(): void {
    this.dispatcher.dispatch(myEvent(), { parent: true });
    // or
    this.dispatcher.dispatch(myEvent(), { root: true });
  }

The proposed approach is lightweight, highly flexible, and aligns naturally with Angular’s design principles.

Describe any alternatives/workarounds you're currently using

While it is possible to include a unique identifier in the event payload and manually filter events within reducers and effects, this approach adds unnecessary overhead and negatively impacts the developer experience.

I would be willing to submit a PR to fix this issue

  • Yes
  • No

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions