diff --git a/website/src/content/docs/core_concepts/event_handler.mdx b/website/src/content/docs/core_concepts/event_handler.mdx index ff0e2943..d6a1d948 100644 --- a/website/src/content/docs/core_concepts/event_handler.mdx +++ b/website/src/content/docs/core_concepts/event_handler.mdx @@ -18,9 +18,9 @@ Reactter offers the following event handler mechanisms: - Methods - [`Reactter.on`](/reactter/methods/event_handler_methods/#reactteron) - [`Reactter.one`](/reactter/methods/event_handler_methods/#reactterone) + - [`Reactter.emit`](/reactter/methods/event_handler_methods/#reactteremit) - [`Reactter.off`](/reactter/methods/event_handler_methods/#reactteroff) - [`Reactter.offAll`](/reactter/methods/event_handler_methods/#reactteroffAll) - - [`Reactter.emit`](/reactter/methods/event_handler_methods/#reactteremit) ## How it works diff --git a/website/src/content/docs/methods/event_handler_methods.mdx b/website/src/content/docs/methods/event_handler_methods.mdx index 09eaf1d7..1cb228cd 100644 --- a/website/src/content/docs/methods/event_handler_methods.mdx +++ b/website/src/content/docs/methods/event_handler_methods.mdx @@ -12,22 +12,547 @@ This documentation assumes you've already read the [Event Handler](/reactter/cor It's recommended read that first if you're new in Reactter. ::: -## Reactter.on +Reactter provides several methods to manage events in a more efficient way. These methods are used to create and manipulate events in a more organized way. -_TODO: Complete this section_ +## `Reactter.on` -## Reactter.one +The `Reactter.on` method listens for an event emitted by an instance, allowing the listener to respond whenever the event occurs. -_TODO: Complete this section_ +#### Syntax -## Reactter.off +```dart +void on( + Object? instance, + Enum eventName, + Functioon(T instance, P param) callback, +); +``` -_TODO: Complete this section_ +#### Parameters -## Reactter.offAll +- `instance`: The `T` instance to listen to. +- `event`: The `Enum` event to listen to. +- `callback`: The function to execute when the event is emitted. The function should accept two parameters: + - `instance`: The `T` instance that emitted the event. + - `param`: The `P` parameter passed when the event is emitted. -_TODO: Complete this section_ +#### Example -## Reactter.emit +See the example below to understand how to use the `Reactter.on` method: -_TODO: Complete this section_ +```dart title="my_controller.dart" collapse={1-100} "Signal" +import 'package:reactter/reactter.dart'; + +enum CustomEvent { myEvent } + +class MyController { + final stateA = Signal(0); + final stateB = Signal('InitialValue'); +} +``` + +```dart title="main.dart" collapse={0-4, 13-16, 37-100} "Reactter.on" "Reactter.create" "Reactter.delete" "Reactter.emit" "Signal" "ReactterDependency" "Lifecycle.didUpdate" +import 'package:reactter/reactter.dart'; +import './my_controller.dart'; + +void main() { + // Listen to the `myEvent` event of the `MyController` instance before it's created + Reactter.on( + ReactterDependency, + CustomEvent.myEvent, + (MyController instance, int param) { + print('Event emitted with param: $param'); + }, + ); + + // Create a new instance of `MyController` + final myController = Reactter.create(() => MyController())!; + + // Listen to the `didUpdate` event of the `MyController` instance + Reactter.on( + myController, + Lifecycle.didUpdate, + (instance, state) => print('State: ${state.runtimeType}'), + ); + + // Listen to the `didUpdate` event of the `stateA` + Reactter.on( + myController.stateA, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State A updated: ${state.value}'), + ); + + // Listen to the `didUpdate` event of the `stateB` + Reactter.on( + myController.stateB, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State B updated: ${state.value}'), + ); + + // Change the value of `stateA` to `10` + // Print: + // State: Signal + // State A updated: 10 + myController.stateA.value = 10; + + // Change the value of `stateB` to `'Hello World!'` + // Print: + // State: Signal + // State B updated: 'Hello World!' + myController.stateB.value = 'Hello World!'; + + // Emit the `myEvent` event with the parameter `42` + // Print: Event emitted with param: 42 + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 42); + + // Delete the `MyController` + Reactter.delete(); + + // Can't change the value of `stateA` + // Error: "Can't update when it's been disposed" + // myController.stateA.value = 20; + + // The `myEvent` event is not emitted, + // because the `MyController` together to the listeners were deleted. + Reactter.emit(ReactterDependency, CustomEvent.myEvent, "test"); +} +``` + +## `Reactter.one` + +The `Reactter.one` method listens for an event emitted by an instance, but only once. After the event is triggered, the listener is automatically removed. + +#### Syntax + +```dart +void one( + Object? instance, + Enum eventName, + Functioon(T instance, P param) callback, +); +``` + +#### Parameters + +- `instance`: The `T` instance to listen to. +- `event`: The `Enum` event to listen to. +- `callback`: The function to execute when the event is emitted. The function should accept two parameters: + - `instance`: The `T` instance that emitted the event. + - `param`: The `P` parameter passed when the event is emitted. + +#### Example + +See the example below to understand how to use the `Reactter.one` method: + +```dart title="main.dart" collapse={0-4, 13-16, 37-100} "Reactter.one" "Reactter.create" "Reactter.delete" "Reactter.emit" "Signal" "ReactterDependency" "Lifecycle.didUpdate" +import 'package:reactter/reactter.dart'; +import './my_controller.dart'; + +void main() { + // Listen to the `myEvent` event of the `MyController` instance before it's created + Reactter.one( + ReactterDependency, + CustomEvent.myEvent, + (MyController instance, int param) { + print('Event emitted with param: $param'); + }, + ); + + // Create a new instance of `MyController` + final myController = Reactter.create(() => MyController())!; + + // Listen to the `didUpdate` event of the `MyController` instance + Reactter.one( + myController, + Lifecycle.didUpdate, + (instance, state) => print('State: ${state.runtimeType}'), + ); + + // Listen to the `didUpdate` event of the `stateA` + Reactter.one( + myController.stateA, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State A updated: ${state.value}'), + ); + + // Listen to the `didUpdate` event of the `stateB` + Reactter.one( + myController.stateB, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State B updated: ${state.value}'), + ); + + // Change the value of `stateA` to `10` + // Print: + // State: Signal + // State A updated: 10 + myController.stateA.value = 10; + + // Change the value of `stateB` to `'Hello World!'` + // Print: + // State B updated: 'Hello World!' + myController.stateB.value = 'Hello World!'; + + // Emit the `myEvent` event with the parameter `42` + // Print: Event emitted with param: 42 + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 42); + + // The `myEvent` event is not listened to again + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 'test'); + + // Delete the `MyController` + Reactter.delete(); + + // Can't change the value of `stateA` + // Error: "Can't update when it's been disposed" + // myController.stateA.value = 20; + + // The `myEvent` event is not listened to again + Reactter.emit(ReactterDependency, CustomEvent.myEvent, "test"); +} +``` + +## `Reactter.emit` + +The `Reactter.emit` method triggers an event from an instance, notifying all listeners of that event. + +#### Syntax + +```dart +void emit( + Object? instance, + Enum eventName, + dynamic param, +); +``` + +#### Parameters + +- `instance`: The instance to emit the event. +- `event`: The `Enum` event to emit. +- `param`: The parameter to pass when emitting the event. + +#### Example + +See the example below to understand how to use the `Reactter.emit` method: + +```dart title="my_controller.dart" collapse={1-100} "Signal" +import 'package:reactter/reactter.dart'; + +enum CustomEvent { myEvent } + +class MyController { + final stateA = Signal(0); + final stateB = Signal('InitialValue'); +} +``` + +```dart title="main.dart" collapse={0-4, 13-16, 37-100} "Reactter.on" "Reactter.create" "Reactter.delete" "Reactter.emit" "Signal" "ReactterDependency" "Lifecycle.didUpdate" +import 'package:reactter/reactter.dart'; +import './my_controller.dart'; + +void main() { + // Listen to the `myEvent` event of the `MyController` instance before it's created + Reactter.on( + ReactterDependency, + CustomEvent.myEvent, + (MyController instance, int param) { + print('Event emitted with param: $param'); + }, + ); + + // Create a new instance of `MyController` + final myController = Reactter.create(() => MyController())!; + + // Listen to the `didUpdate` event of the `MyController` instance + Reactter.on( + myController, + Lifecycle.didUpdate, + (instance, state) => print('State: ${state.runtimeType}'), + ); + + // Listen to the `didUpdate` event of the `stateA` + Reactter.on( + myController.stateA, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State A updated: ${state.value}'), + ); + + // Listen to the `didUpdate` event of the `stateB` + Reactter.on( + myController.stateB, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State B updated: ${state.value}'), + ); + + // Change the value of `stateA` to `10` + // Print: + // State: Signal + // State A updated: 10 + myController.stateA.value = 10; + + // Change the value of `stateB` to `'Hello World!'` + // Print: + // State: Signal + // State B updated: 'Hello World!' + myController.stateB.value = 'Hello World!'; + + // Emit the `myEvent` event with the parameter `42` + // Print: Event emitted with param: 42 + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 42); + + // Delete the `MyController` + Reactter.delete(); + + // Can't change the value of `stateA` + // Error: "Can't update when it's been disposed" + // myController.stateA.value = 20; + + // The `myEvent` event is not emitted, + // because the `MyController` together to the listeners were deleted. + Reactter.emit(ReactterDependency, CustomEvent.myEvent, "test"); +} +``` + + +## `Reactter.off` + +The `Reactter.off` method removes a specific event listener from an instance, stopping it from receiving further notifications for that event. + +#### Syntax + +```dart +void off( + Object? instance, + Enum eventName, + Functioon(T instance, P param) callback, +); +``` + +#### Parameters + +- `instance`: The `T` instance to stop listening to. +- `event`: The `Enum` event to stop listening to. +- - `callback`: The function to stop executing the callback. The function should accept two parameters: + - `instance`: The `T` instance that emitted the event. + - `param`: The `P` parameter passed when the event is emitted. + +#### Example + +See the example below to understand how to use the `Reactter.off` method: + +```dart title="my_controller.dart" collapse={1-100} "Signal" +import 'package:reactter/reactter.dart'; + +enum CustomEvent { myEvent } + +class MyController { + final stateA = Signal(0); + final stateB = Signal('InitialValue'); +} +``` + +```dart title="main.dart" collapse={1-67, 74-78, 85-89, 96-100} "Reactter.on" "Reactter.off" "Reactter.create" "Reactter.delete" "Reactter.emit" "Signal" "ReactterDependency" "Lifecycle.didUpdate" +import 'package:reactter/reactter.dart'; +import './my_controller.dart'; + +void onMyEvent(instance, param) { + print('Event emitted with param: $param'); +} + +void onDidUpdate(instance, state) { + print('State: ${state.runtimeType}'); +} + +void onDidUpdateStateA(MyController instance, Signal state) { + print('State A updated: ${state.value}'); +} + +void onDidUpdateStateB(MyController instance, Signal state) { + print('State B updated: ${state.value}'); +} + +void main() { + // Listen to the `myEvent` event of the `MyController` instance before it's created + Reactter.on( + ReactterDependency, + CustomEvent.myEvent, + onMyEvent, + ); + + // Create a new instance of `MyController` + final myController = Reactter.create(() => MyController())!; + + // Listen to the `didUpdate` event of the `MyController` instance + Reactter.on( + myController, + Lifecycle.didUpdate, + onDidUpdate, + ); + + // Listen to the `didUpdate` event of the `stateA` + Reactter.on( + myController.stateA, + Lifecycle.didUpdate, + onDidUpdateStateA, + ); + + // Listen to the `didUpdate` event of the `stateB` + Reactter.on( + myController.stateB, + Lifecycle.didUpdate, + didUpdateStateBListener, + ); + + // Change the value of `stateA` to `10` + // Print: + // State: Signal + // State A updated: 10 + myController.stateA.value = 10; + + // Change the value of `stateB` to `'Hello World!'` + // Print: + // State: Signal + // State B updated: 'Hello World!' + myController.stateB.value = 'Hello World!'; + + // Emit the `myEvent` event with the parameter `42` + // Print: Event emitted with param: 42 + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 42); + + // Stop listening to the `didUpdate` event of the `stateA` + Reactter.off( + myController.stateA, + Lifecycle.didUpdate, + onDidUpdateStateA, + ); + + // Change the value of `stateA` to `20` + // Print: State: Signal + myController.stateA.value = 20; + + // Stop listening to the `didUpdate` event of the `MyController` instance + Reactter.off( + myController, + Lifecycle.didUpdate, + onDidUpdate, + ); + + // Change the value of `stateB` to `'Hey you!'` + // Print: State B updated: 'Hey you!' + myController.stateB.value = 'Hey you!'; + + // Stop listening to the `myEvent` event of the `MyController` instance + Reactter.off( + ReactterDependency, + CustomEvent.myEvent, + onMyEvent, + ); + + // Emit the `myEvent` event with the parameter `test` + // The `myEvent` event is not listened to again + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 'test'); +} +``` + +## `Reactter.offAll` + +The `Reactter.offAll` method removes all event listeners for a specific event from an instance, ensuring no listeners are notified when the event is triggered in the future. + +#### Syntax + +```dart +void offAll(Object? instance); +``` + +#### Parameters + +- `instance`: The `T` instance to stop listening to all events. + +#### Example + +See the example below to understand how to use the `Reactter.offAll` method: + +```dart title="my_controller.dart" collapse={1-100} "Signal" +import 'package:reactter/reactter.dart'; + +enum CustomEvent { myEvent } + +class MyController { + final stateA = Signal(0); + final stateB = Signal('InitialValue'); +} +``` + +```dart title="main.dart" collapse={1-51, 54-100} "Reactter.on" "Reactter.offAll" "Reactter.create" "Reactter.delete" "Reactter.emit" "Signal" "ReactterDependency" "Lifecycle.didUpdate" +import 'package:reactter/reactter.dart'; +import './my_controller.dart'; + +void main() { + // Listen to the `myEvent` event of the `MyController` instance before it's created + Reactter.on( + ReactterDependency, + CustomEvent.myEvent, + (instance, param) => print('Event emitted with param: $param'), + ); + + // Create a new instance of `MyController` + final myController = Reactter.create(() => MyController())!; + + // Listen to the `didUpdate` event of the `MyController` instance + Reactter.on( + myController, + Lifecycle.didUpdate, + (instance, state) => print('State: ${state.runtimeType}'), + ); + + // Listen to the `didUpdate` event of the `stateA` + Reactter.on( + myController.stateA, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State A updated: ${state.value}'), + ); + + // Listen to the `didUpdate` event of the `stateB` + Reactter.on( + myController.stateB, + Lifecycle.didUpdate, + (MyController instance, Signal state) => print('State B updated: ${state.value}'), + ); + + // Change the value of `stateA` to `10` + // Print: + // State: Signal + // State A updated: 10 + myController.stateA.value = 10; + + // Change the value of `stateB` to `'Hello World!'` + // Print: + // State: Signal + // State B updated: 'Hello World!' + myController.stateB.value = 'Hello World!'; + + // Emit the `myEvent` event with the parameter `42` + // Print: Event emitted with param: 42 + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 42); + + // Stop listening to all events of the `MyController` instance + Reactter.offAll(myController); + + // Change the value of `stateA` to `20` + // The `didUpdate` event of `MyController` instance is not listened to + // Print: + // State A updated: 20 + myController.stateA.value = 20; + + // Change the value of `stateB` to `'Hey you!'` + // The `didUpdate` event of `MyController` instance is not listened to + // Print: + // State B updated: 'Hey you!' + myController.stateB.value = 'Hey you!'; + + // Emit the `myEvent` event with the parameter `test` + // The `myEvent` event of `MyController` instance is not listened to + Reactter.emit(ReactterDependency, CustomEvent.myEvent, 'test'); +} +```