Basically this is the solution I ended up using.
$apply() should only be used by external sources in the right circumstances.
rather then using apply, I've thrown the scope updating to end of the call stack. Works as good as "scope.$apply(attrs.imageonload)(true);".
window.app.directive("onImageload", ["$timeout", function($timeout) {
function timeOut(value, scope) {
$timeout(function() {
scope.imageLoaded = value;
});
}
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
timeOut(true, scope);
}).bind('error', function() {
timeOut(false, scope);
});
}
};
}]);