Parsing HTML generated outside of Angular
It often happens that you have to work on some old project using jQuery. But in modern Web Development jQuery just doesn't cut it. So you write new features in Angular. But sometimes you have to modify existing code.
It's not a problem as long as HTML is static, but if it's generated on server side Rails+jQuery style, then Angular won't know anything about it when it arrives to a browser.
So we have make Angular parse this HTML. I remember a long time ago when I first encountered that problem I googled quite a lot but came up empty handed. So I had to find a way myself. Recently my colleagues stumbled on the same problem so I decided to share this little piece of code on the internets.
var $injector = angular.element(document).injector(); // first we get the injector our app uses | |
$injector.invoke(function($rootScope, $compile) { // you inject anything here in params | |
var element = angular.element('#selector'); // get the element we want to parse | |
// following hack isn't always neccessary, but I use to prevent double parsing if the same HTML is generated statically and dynamically | |
if (element.attr('class') && element.attr('class').indexOf("ng-scope")!=-1){ | |
return; | |
} | |
var compiled = $compile(element)($rootScope); // finally, we compile the element against root scope | |
compiled.scope().$apply(); // ... and we tell Angular that we made changes outside of its 'world' | |
}); |
Well... That's pretty much it. You shouldn't try running your angular app again. It's going to create a separate application.
Also I want to share an interesting gotcha. If you inline your angular templates with
<script type="text/ng-template" id="the-template" >
and they are in dynamically generated HTML you have parse this HTML. Strangely enough Angular doesn't use selectors to get this template. Rather it puts this template into template cache when encounters it during parsing.