react-native-navigation的迁移库

LayoutTreeCrawler.ts 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. }
  43. _savePropsToStore(node) {
  44. this.store.setPropsForId(node.id, node.data.passProps);
  45. }
  46. _applyStaticOptions(node) {
  47. const clazz = this.store.getOriginalComponentClassForName(node.data.name) || {};
  48. const staticOptions = _.cloneDeep(clazz.options) || {};
  49. const passedOptions = node.data.options || {};
  50. node.data.options = _.merge({}, staticOptions, passedOptions);
  51. }
  52. _assertKnownLayoutType(type) {
  53. if (!LayoutType[type]) {
  54. throw new Error(`Unknown layout type ${type}`);
  55. }
  56. }
  57. _assertComponentDataName(component) {
  58. if (!component.data.name) {
  59. throw new Error('Missing component data.name');
  60. }
  61. }
  62. }