rebuild_on_change.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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(value, oldValue) {
  45. if (childScope && value !== oldValue) {
  46. cleanUp();
  47. }
  48. if (!childScope && (value || attrs.showNull)) {
  49. transclude(function(clone, newScope) {
  50. childScope = newScope;
  51. clone[clone.length++] = document.createComment(' end rebuild on change ');
  52. block = { clone: clone };
  53. $animate.enter(clone, elem.parent(), elem);
  54. });
  55. } else {
  56. cleanUp();
  57. }
  58. });
  59. },
  60. };
  61. }
  62. coreModule.directive('rebuildOnChange', rebuildOnChange);