react-native-navigation的迁移库

LayoutTreeCrawler.ts 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import * as _ from 'lodash';
  2. import { OptionsProcessor } from './OptionsProcessor';
  3. import { LayoutType } from './LayoutType';
  4. export interface Data {
  5. name?: string;
  6. options?: any;
  7. passProps?: any;
  8. }
  9. export interface LayoutNode {
  10. id?: string;
  11. type: LayoutType;
  12. data: Data;
  13. children: LayoutNode[];
  14. }
  15. export class LayoutTreeCrawler {
  16. private optionsProcessor: OptionsProcessor;
  17. constructor(
  18. private readonly uniqueIdProvider: any,
  19. public readonly store: any) {
  20. this.crawl = this.crawl.bind(this);
  21. this.processOptions = this.processOptions.bind(this);
  22. this.optionsProcessor = new OptionsProcessor(store, uniqueIdProvider);
  23. }
  24. crawl(node: LayoutNode): void {
  25. this._assertKnownLayoutType(node.type);
  26. node.id = node.id || this.uniqueIdProvider.generate(node.type);
  27. node.data = node.data || {};
  28. node.children = node.children || [];
  29. if (node.type === LayoutType.Component) {
  30. this._handleComponent(node);
  31. }
  32. this.processOptions(node.data.options);
  33. _.forEach(node.children, this.crawl);
  34. }
  35. processOptions(options) {
  36. this.optionsProcessor.processOptions(options);
  37. }
  38. _handleComponent(node) {
  39. this._assertComponentDataName(node);
  40. this._savePropsToStore(node);
  41. this._applyStaticOptions(node);
  42. node.data.passProps = undefined;
  43. }
  44. _savePropsToStore(node) {
  45. this.store.setPropsForId(node.id, node.data.passProps);
  46. }
  47. _applyStaticOptions(node) {
  48. const clazz = this.store.getComponentClassForName(node.data.name) ? this.store.getComponentClassForName(node.data.name)() : {};
  49. const staticOptions = _.isFunction(clazz.options) ? clazz.options(node.data.passProps || {}) : (_.cloneDeep(clazz.options) || {});
  50. const passedOptions = node.data.options || {};
  51. node.data.options = _.merge({}, staticOptions, passedOptions);
  52. }
  53. _assertKnownLayoutType(type) {
  54. if (!LayoutType[type]) {
  55. throw new Error(`Unknown layout type ${type}`);
  56. }
  57. }
  58. _assertComponentDataName(component) {
  59. if (!component.data.name) {
  60. throw new Error('Missing component data.name');
  61. }
  62. }
  63. }