Skip to content

Commit

Permalink
#cnsqa-1683 merge
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasPan committed Dec 18, 2024
2 parents 2500a23 + 6cc3a47 commit 0fafe80
Show file tree
Hide file tree
Showing 60 changed files with 3,314 additions and 377 deletions.
7 changes: 7 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & JavaScript",
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm",
"postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}"
}
106 changes: 88 additions & 18 deletions docs/basic-features/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,6 @@ way to propagate event in other directions, or to other parts of the UI, or
from the controller to the UI is using the `app/event/Dispatcher` API.

**Accessing Dispatcher in Controllers** is easy with [Dependency Injection](./object-container.md#1-dependency-injection).
**To access Dispatcher from Views and Components** you should register it in [ComponentUtils](./views-and-components.md#utilities-shared-across-views-and-components).

```javascript
// app/config/bind.js
import { Dispatcher } from '@ima/core';

export let init = (ns, oc, config) => {
const ComponentUtils = oc.get('$ComponentUtils');

ComponentUtils.register({
$Dispatcher: Dispatcher
});
}
```


### Firing and listening to Dispatcher events
Expand Down Expand Up @@ -195,10 +181,94 @@ will still receive the `showLightbox` event when it's fired.
> **Note:** A great place to
mount components like Lightbox is [ManagedRootView](./rendering-process.md#managedrootview).

Note that events distributed using the Dispatcher are useful only in very
specific use-cases, so the Dispatcher logs a warning to the console if there
are no listeners registered for the fired event in order to notify you of
possible typos in event names.
### Listening to all Dispatcher events

You can listen to all events dispatched by the `Dispatcher` by using the `listenAll()`
and `unlistenAll()` methods.

```javascript
// app/component/eventLogger/EventLogger.jsx

componentDidMount() {
this.utils.$Dispatcher.listenAll(this._onDispatcherEvent, this);
}

componentWillUnmount() {
this.utils.$Dispatcher.unlistenAll(this._onDispatcherEvent, this);
}

_onDispatcherEvent(eventName, data) {
// ...
}
```

## Observable

The `Observable` class allows you to subscribe to events dispatched by the
`Dispatcher`. Upon subscribing, subscribers will be notified of past and future
events.

**Accessing Observable in Controllers** is easy with [Dependency Injection](./object-container.md#1-dependency-injection).

### Subscribing and unsubscribing to events

You can subscribe to events dispatched by the `Dispatcher` using the `subscribe()`, and unsubscribe using the `unsubscribe()` method.

```javascript
// app/component/media/Media.jsx

componentDidMount() {
this.utils.$Observable.subscribe('showLightbox', this._onShowLightbox, this);
}

componentWillUnmount() {
this.utils.$Observable.unsubscribe('showLightbox', this._onShowLightbox, this);
}

_onShowLightbox(data) {
// ...
}
```

> **Note:** If the `showLightbox` event was already dispatched before the `Media` component was mounted,
the `_onShowLightbox` method will be called immediately upon subscribing with the data that was passed to the event.
> **Note:** If the event was dispatched multiple times before the `Media` component was mounted,
the `_onShowLightbox` method will be called for each event.

### Persistent events

The `Observable` class clears its history of dispatched events when the `RouterEvents.BEFORE_HANDLE_ROUTE` event is dispatched.
If you want to keep the history of dispatched events, you can use the `registerPersistentEvent()` method.

```javascript
// app/config/services.js

export const initServicesApp = (ns, oc, config) => {
const Observable = oc.get('$Observable');

Observable.registerPersistentEvent('scriptLoaded');
}
```

### Settings

By default, the `Observable` class holds the last 10 events dispatched by the `Dispatcher`.
You can change this by modifying the `$Observable.maxHistoryLength` setting.

```javascript
// app/config/settings.js

export default (ns, oc, config) => {
return {
prod: {
// ...
$Observable: {
maxHistoryLength: 20
}
}
};
}
```

## Built-in events

Expand Down
11 changes: 11 additions & 0 deletions docs/basic-features/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ test('renders component with custom app configuration', async () => {
});
```

### renderHookWithContext

```javascript
async function renderHookWithContext<TResult, TProps>(
hook: (props: TProps) => TResult,
options?: { contextValue?: ContextValue; app?: ImaApp }
): Promise<ReturnType<typeof renderHook<TResult, TProps>> & { app: ImaApp | null; contextValue: ContextValue; }>
```

`renderHookWithContext` is a wrapper around [`renderHook` from `@testing-library/react`](https://testing-library.com/docs/react-testing-library/api#renderhook). It uses the same logic as `renderWithContext` to provide the IMA.js context. See [the `renderWithContext` section](#renderwithcontext) for more information.

## Extending IMA boot config methods

You can extend IMA boot config by using [IMA `pluginLoader.register`](https://imajs.io/api/classes/ima_core.PluginLoader/#register) method. Use the same approach as in IMA plugins.
Expand Down
Loading

0 comments on commit 0fafe80

Please sign in to comment.