react-native-navigation的迁移库

LayoutTreeCrawler.ts 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import * as _ from 'lodash';
  2. import { OptionsProcessor } from './OptionsProcessor';
  3. import { LayoutType, isLayoutType } 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 = new OptionsProcessor();
  17. constructor(
  18. private readonly uniqueIdProvider: any,
  19. public readonly store: any) {
  20. this.crawl = this.crawl.bind(this);
  21. }
  22. crawl(node: LayoutNode): void {
  23. this._assertKnownLayoutType(node.type);
  24. node.id = node.id || this.uniqueIdProvider.generate(node.type);
  25. node.data = node.data || {};
  26. node.children = node.children || [];
  27. if (node.type === LayoutType.Component) {
  28. this._handleComponent(node);
  29. }
  30. this.optionsProcessor.processOptions(node.data.options, this.store);
  31. _.forEach(node.children, this.crawl);
  32. }
  33. _handleComponent(node) {
  34. this._assertComponentDataName(node);
  35. this._savePropsToStore(node);
  36. this._applyStaticOptions(node);
  37. }
  38. _savePropsToStore(node) {
  39. this.store.setPropsForId(node.id, node.data.passProps);
  40. }
  41. _applyStaticOptions(node) {
  42. const clazz = this.store.getOriginalComponentClassForName(node.data.name) || {};
  43. const staticOptions = _.cloneDeep(clazz.options) || {};
  44. const passedOptions = node.data.options || {};
  45. node.data.options = _.merge({}, staticOptions, passedOptions);
  46. }
  47. _assertKnownLayoutType(type) {
  48. if (!isLayoutType(type)) {
  49. throw new Error(`Unknown layout type ${type}`);
  50. }
  51. }
  52. _assertComponentDataName(component) {
  53. if (!component.data.name) {
  54. throw new Error('Missing component data.name');
  55. }
  56. }
  57. }