Last active
September 28, 2016 19:53
-
-
Save kentcdodds/739566ebd3609ac95e61 to your computer and use it in GitHub Desktop.
kcd-recompile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
}); | |
} | |
}; | |
}]); |
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
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.