react-native-navigation的迁移库

ComponentEventsObserver.ts 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. export class ComponentEventsObserver {
  15. private readonly listeners = {};
  16. private alreadyRegistered = false;
  17. constructor(private readonly nativeEventsReceiver: NativeEventsReceiver) {
  18. this.notifyComponentDidAppear = this.notifyComponentDidAppear.bind(this);
  19. this.notifyComponentDidDisappear = this.notifyComponentDidDisappear.bind(this);
  20. this.notifyNavigationButtonPressed = this.notifyNavigationButtonPressed.bind(this);
  21. this.notifyModalDismissed = this.notifyModalDismissed.bind(this);
  22. this.notifySearchBarUpdated = this.notifySearchBarUpdated.bind(this);
  23. this.notifySearchBarCancelPressed = this.notifySearchBarCancelPressed.bind(this);
  24. this.notifyPreviewCompleted = this.notifyPreviewCompleted.bind(this);
  25. }
  26. public registerOnceForAllComponentEvents() {
  27. if (this.alreadyRegistered) { return; }
  28. this.alreadyRegistered = true;
  29. this.nativeEventsReceiver.registerComponentDidAppearListener(this.notifyComponentDidAppear);
  30. this.nativeEventsReceiver.registerComponentDidDisappearListener(this.notifyComponentDidDisappear);
  31. this.nativeEventsReceiver.registerNavigationButtonPressedListener(this.notifyNavigationButtonPressed);
  32. this.nativeEventsReceiver.registerModalDismissedListener(this.notifyModalDismissed);
  33. this.nativeEventsReceiver.registerSearchBarUpdatedListener(this.notifySearchBarUpdated);
  34. this.nativeEventsReceiver.registerSearchBarCancelPressedListener(this.notifySearchBarCancelPressed);
  35. this.nativeEventsReceiver.registerPreviewCompletedListener(this.notifyPreviewCompleted);
  36. }
  37. public bindComponent(component: React.Component<any>, componentId?: string): EventSubscription {
  38. const computedComponentId = componentId || component.props.componentId;
  39. if (!_.isString(computedComponentId)) {
  40. throw new Error(`bindComponent expects a component with a componentId in props or a componentId as the second argument`);
  41. }
  42. if (_.isNil(this.listeners[computedComponentId])) {
  43. this.listeners[computedComponentId] = {};
  44. }
  45. const key = _.uniqueId();
  46. this.listeners[computedComponentId][key] = component;
  47. return { remove: () => _.unset(this.listeners[computedComponentId], key) };
  48. }
  49. public unmounted(componentId: string) {
  50. _.unset(this.listeners, componentId);
  51. }
  52. notifyComponentDidAppear(event: ComponentDidAppearEvent) {
  53. this.triggerOnAllListenersByComponentId(event, 'componentDidAppear');
  54. }
  55. notifyComponentDidDisappear(event: ComponentDidDisappearEvent) {
  56. this.triggerOnAllListenersByComponentId(event, 'componentDidDisappear');
  57. }
  58. notifyNavigationButtonPressed(event: NavigationButtonPressedEvent) {
  59. this.triggerOnAllListenersByComponentId(event, 'navigationButtonPressed');
  60. }
  61. notifyModalDismissed(event: ModalDismissedEvent) {
  62. this.triggerOnAllListenersByComponentId(event, 'modalDismissed');
  63. }
  64. notifySearchBarUpdated(event: SearchBarUpdatedEvent) {
  65. this.triggerOnAllListenersByComponentId(event, 'searchBarUpdated');
  66. }
  67. notifySearchBarCancelPressed(event: SearchBarCancelPressedEvent) {
  68. this.triggerOnAllListenersByComponentId(event, 'searchBarCancelPressed');
  69. }
  70. notifyPreviewCompleted(event: PreviewCompletedEvent) {
  71. this.triggerOnAllListenersByComponentId(event, 'previewCompleted');
  72. }
  73. private triggerOnAllListenersByComponentId(event: ComponentEvent, method: string) {
  74. _.forEach(this.listeners[event.componentId], (component) => {
  75. if (_.isObject(component) && _.isFunction(component[method])) {
  76. component[method](event);
  77. }
  78. });
  79. }
  80. }