Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Last active September 28, 2016 19:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kentcdodds/739566ebd3609ac95e61 to your computer and use it in GitHub Desktop.
Save kentcdodds/739566ebd3609ac95e61 to your computer and use it in GitHub Desktop.
kcd-recompile
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();
});
}
};
}]);
@CWSpear
Copy link

CWSpear commented Sep 10, 2014

How (or I guess, why) does this differ from the one in your video: https://www.youtube.com/watch?v=hFOSXVT-Cps?

@kentcdodds
Copy link
Author

@CWSpear, sorry, I don't get notifications when comments are placed on my gists. I just updated this code. Hopefully this is helpful!

@devonsams
Copy link

devonsams commented Sep 15, 2016

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.

@edriang
Copy link

edriang commented Sep 28, 2016

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