rebuild_on_change.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import $ from 'jquery';
  2. import coreModule from './core_module';
  3. function getBlockNodes(nodes: any[]) {
  4. let node = nodes[0];
  5. const endNode = nodes[nodes.length - 1];
  6. let blockNodes: any[] | undefined;
  7. node = node.nextSibling;
  8. for (let i = 1; node !== endNode && node; i++) {
  9. if (blockNodes || nodes[i] !== node) {
  10. if (!blockNodes) {
  11. blockNodes = $([].slice.call(nodes, 0, i)) as any;
  12. }
  13. blockNodes!.push(node);
  14. }
  15. node = node.nextSibling;
  16. }
  17. return blockNodes || nodes;
  18. }
  19. /** @ngInject */
  20. function rebuildOnChange($animate: any) {
  21. return {
  22. multiElement: true,
  23. terminal: true,
  24. transclude: true,
  25. priority: 600,
  26. restrict: 'E',
  27. link: (scope: any, elem: any, attrs: any, ctrl: any, transclude: any) => {
  28. let block: any, childScope: any, previousElements: any;
  29. function cleanUp() {
  30. if (previousElements) {
  31. previousElements.remove();
  32. previousElements = null;
  33. }
  34. if (childScope) {
  35. childScope.$destroy();
  36. childScope = null;
  37. }
  38. if (block) {
  39. previousElements = getBlockNodes(block.clone);
  40. $animate.leave(previousElements).then(() => {
  41. previousElements = null;
  42. });
  43. block = null;
  44. }
  45. }
  46. scope.$watch(attrs.property, function rebuildOnChangeAction(value: any, oldValue: any) {
  47. if (childScope && value !== oldValue) {
  48. cleanUp();
  49. }
  50. if (!childScope && (value || attrs.showNull)) {
  51. transclude((clone: any, newScope: any) => {
  52. childScope = newScope;
  53. clone[clone.length++] = document.createComment(' end rebuild on change ');
  54. block = { clone: clone };
  55. $animate.enter(clone, elem.parent(), elem);
  56. });
  57. } else {
  58. cleanUp();
  59. }
  60. });
  61. },
  62. };
  63. }
  64. coreModule.directive('rebuildOnChange', rebuildOnChange);