rebuild_on_change.ts 1.8 KB

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