Our webapplication currently has a collapsable side menu, the logic of which is handled via an external library called CleanZone. The problem occurs with loading submenu items. These are appended to the DOM after page load when the menu is collapsed, causing click event handlers (passed via ng-click) to not respond.
Normally for stuff like this, we'd create a directive and append it to the DOM via the $compile service. However in this case, I need to rely on the logic of this external library, which itself doesn't use AngularJS.
Is it possible to somehow catch whatever this library added to the HTML, recompile it through AngularJS, so that the ng-click event works for it?
Here's the code to help understand the problem:
The DOM contains this at all times:
<ul class="sub-menu">
<li>
<a ng-click="someFunction()" href="#">Text</a>
</li>
</ul>
If the menu is not collapsed, above submenu is shown, as it was already in the DOM, ng-click just works.
However when the menu is collapsed, the user has to hover over an icon on the menu, and the submenu is then appended dynamically:
<div id="sub-menu-nav">
<ul class="sub-menu">
<li>
<a ng-click="someFunction()" href="#"></a>
</li>
</ul>
</div>
Here's the relevant part of how that library adds the element:
/*SubMenu hover */
var tool = $("<div id='sub-menu-nav' style='position:fixed;z-index:9999;'></div>");
function showMenu(_this, e) {
if (($("#cl-wrapper").hasClass("sb-collapsed")) {
var menu = $("ul", _this);
tool.appendTo("body");
tool.html('<ul class="sub-menu">' + menu.html() + '</ul>');
tool.show();
} else {
tool.hide();
}
}
$(".cl-vnavigation li").hover(function (e) {
showMenu(this, e);
}, function (e) {
tool.removeClass("over");
setTimeout(function () {
if (!tool.hasClass("over") && !$(".cl-vnavigation li:hover").length > 0) {
tool.hide();
}
}, 500);
});
I've attempted to use a directive, but it has the same behaviour ie. only the element that already was in the DOM initially will respond to click events.
For completeness sake, here's the directive:
app.directive("testAnchor", function ($compile) {
return {
restrict: "E",
replace: true,
scope: { onClick: '&' },
template: '<a href="#" ng-click="onClick({arg1: string, arg2: string})>TestText!</a>',
link: function (scope, element, attrs) {
$compile(element.contents())(scope.$new());
}
}
});
And I call it like this:
<test-anchor on-click="myFunction(argument1, argument2)"></test-anchor>
I had hoped AngularJS would compile the appended directive, but it apparently doesn't work that way.
So: Can AngularJS compile HTML appended by an external library after load?