react-native-navigation的迁移库

ComponentEventsObserver.ts 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import * as _ from 'lodash';
  2. import { EventSubscription } from '../interfaces/EventSubscription';
  3. import {
  4. ComponentDidAppearEvent,
  5. ComponentDidDisappearEvent,
  6. NavigationButtonPressedEvent,
  7. SearchBarUpdatedEvent,
  8. SearchBarCancelPressedEvent,
  9. ComponentEvent,
  10. PreviewCompletedEvent,
  11. ModalDismissedEvent
  12. } from '../interfaces/ComponentEvents';
  13. import { NativeEventsReceiver } from '../adapters/NativeEventsReceiver';
  14. import { Store } from '../components/Store';
  15. type ReactComponentWithIndexing = React.Component<any> & Record<string, any>;
  16. export class ComponentEventsObserver {
  17. private listeners: Record<string, Record<string, ReactComponentWithIndexing>> = {};
  18. private alreadyRegistered = false;
  19. constructor(
  20. private readonly nativeEventsReceiver: NativeEventsReceiver,
  21. private readonly store: Store
  22. ) {
  23. this.notifyComponentDidAppear = this.notifyComponentDidAppear.bind(this);
  24. this.notifyComponentDidDisappear = this.notifyComponentDidDisappear.bind(this);
  25. this.notifyNavigationButtonPressed = this.notifyNavigationButtonPressed.bind(this);
  26. this.notifyModalDismissed = this.notifyModalDismissed.bind(this);
  27. this.notifySearchBarUpdated = this.notifySearchBarUpdated.bind(this);
  28. this.notifySearchBarCancelPressed = this.notifySearchBarCancelPressed.bind(this);
  29. this.notifyPreviewCompleted = this.notifyPreviewCompleted.bind(this);
  30. }
  31. public registerOnceForAllComponentEvents() {
  32. if (this.alreadyRegistered) { return; }
  33. this.alreadyRegistered = true;
  34. this.nativeEventsReceiver.registerComponentDidAppearListener(this.notifyComponentDidAppear);
  35. this.nativeEventsReceiver.registerComponentDidDisappearListener(this.notifyComponentDidDisappear);
  36. this.nativeEventsReceiver.registerNavigationButtonPressedListener(this.notifyNavigationButtonPressed);
  37. this.nativeEventsReceiver.registerModalDismissedListener(this.notifyModalDismissed);
  38. this.nativeEventsReceiver.registerSearchBarUpdatedListener(this.notifySearchBarUpdated);
  39. this.nativeEventsReceiver.registerSearchBarCancelPressedListener(this.notifySearchBarCancelPressed);
  40. this.nativeEventsReceiver.registerPreviewCompletedListener(this.notifyPreviewCompleted);
  41. }
  42. public bindComponent(component: React.Component<any>, componentId?: string): EventSubscription {
  43. const computedComponentId = componentId || component.props.componentId;
  44. if (!_.isString(computedComponentId)) {
  45. throw new Error(`bindComponent expects a component with a componentId in props or a componentId as the second argument`);
  46. }
  47. if (_.isNil(this.listeners[computedComponentId])) {
  48. this.listeners[computedComponentId] = {};
  49. }
  50. const key = _.uniqueId();
  51. this.listeners[computedComponentId][key] = component;
  52. return { remove: () => _.unset(this.listeners[computedComponentId], key) };
  53. }
  54. public unmounted(componentId: string) {
  55. _.unset(this.listeners, componentId);
  56. }
  57. notifyComponentDidAppear(event: ComponentDidAppearEvent) {
  58. event.passProps = this.store.getPropsForId(event.componentId);
  59. this.triggerOnAllListenersByComponentId(event, 'componentDidAppear');
  60. }
  61. notifyComponentDidDisappear(event: ComponentDidDisappearEvent) {
  62. this.triggerOnAllListenersByComponentId(event, 'componentDidDisappear');
  63. }
  64. notifyNavigationButtonPressed(event: NavigationButtonPressedEvent) {
  65. this.triggerOnAllListenersByComponentId(event, 'navigationButtonPressed');
  66. }
  67. notifyModalDismissed(event: ModalDismissedEvent) {
  68. this.triggerOnAllListenersByComponentId(event, 'modalDismissed');
  69. }
  70. notifySearchBarUpdated(event: SearchBarUpdatedEvent) {
  71. this.triggerOnAllListenersByComponentId(event, 'searchBarUpdated');
  72. }
  73. notifySearchBarCancelPressed(event: SearchBarCancelPressedEvent) {
  74. this.triggerOnAllListenersByComponentId(event, 'searchBarCancelPressed');
  75. }
  76. notifyPreviewCompleted(event: PreviewCompletedEvent) {
  77. this.triggerOnAllListenersByComponentId(event, 'previewCompleted');
  78. }
  79. private triggerOnAllListenersByComponentId(event: ComponentEvent, method: string) {
  80. _.forEach(this.listeners[event.componentId], (component) => {
  81. if (component && component[method]) {
  82. component[method](event);
  83. }
  84. });
  85. }
  86. }