-
-
Save kentcdodds/739566ebd3609ac95e61 to your computer and use it in GitHub Desktop.
| angular.module('kcd.directives').directive('kcdRecompile', ['$parse', function($parse) { | |
| 'use strict'; | |
| return { | |
| transclude: true, | |
| link: function link(scope, $el, attrs, ctrls, transclude) { | |
| var previousElements; | |
| compile(); | |
| function compile() { | |
| transclude(scope, function(clone, clonedScope) { | |
| // transclude creates a clone containing all children elements; | |
| // as we assign the current scope as first parameter, the clonedScope is the same | |
| previousElements = clone; | |
| $el.append(clone); | |
| }); | |
| } | |
| function recompile() { | |
| if (previousElements) { | |
| previousElements.remove(); | |
| previousElements = null; | |
| $el.empty(); | |
| } | |
| compile(); | |
| } | |
| scope.$watch(attrs.kcdRecompile, function(_new, _old) { | |
| var useBoolean = attrs.hasOwnProperty('useBoolean'); | |
| if ((useBoolean && (!_new || _new === 'false')) || (!useBoolean && (!_new || _new === _old))) { | |
| return; | |
| } | |
| // reset kcdRecompile to false if we're using a boolean | |
| if (useBoolean) { | |
| $parse(attrs.kcdRecompile).assign(scope, false); | |
| } | |
| recompile(); | |
| }); | |
| } | |
| }; | |
| }]); |
Came across an interesting issue. I'm still debugging, but it appears that child component scopes are never destroyed when I do a recompile using this directive. Say I have the following:
<div kcd-recompile="$ctrl.reload" use-boolean>
<custom-component ng-repeat="item in ::$ctrl.items"></custom-component>
</div>
After I set this.reload = true in the parent component controller and I see the ng-repeat recompile, if I check the scope tree in batarang, I can see all of the old custom-component scopes still hanging out there, and they continue to stack up each time I recompile.
I'm wondering if I should add this.$element.on('destroy', () => this.$scope.destroy()) to any child components I want to use within a kcd-recompile element, or if there's a way for that to be handled from within the kcd-recompile directive itself.
Nice library, but I was having problems in some use cases, and after couple of hours noticed that if attrs.kcdRecompile evaluated in true in the first time, then $watch was called with _new and _old with "true" values and was forcing a new recompile(), while It shouldn't because compile() was already called when directive compiled.
I Had to add if(_new !== _old){recompile();} at the end of the $watch function in order to work properly.
@CWSpear, sorry, I don't get notifications when comments are placed on my gists. I just updated this code. Hopefully this is helpful!