I would like to create a ngLoad
directive for images on my webpage. This is my preferred markup:
<img ng-src="{{ src }}" ng-load="onLoad()">
Right now, I have a imgLoad
directive with ngLoad
specified in the scope
, like so:
var app = angular.module('app', []);
app.directive('imgLoad', [function() {
return {
restrict: 'A',
scope: {
loadHandler: '&ngLoad'
},
link: function (scope, element, attr) {
element.on('load', scope.loadHandler);
}
};
}]);
The resulting markup is:
<img ng-src="{{ src }}" img-load ng-load="onLoad()">
Edit: I previously assumed that the name of the directive (i.e. imgLoad
) needed to be different from the name of my attribute (i.e. ngLoad
). This is not the case. The solution is to name my directive ngLoad
.
I want to get rid of the imgLoad
attribute. I want ngLoad
to work regardless of any other attributes.
My implementation is based on:
Any help is much appreciated!
Thanks to @smk for this answer
Give the directive and the scope property the same name.
app.directive('imgLoad', function() { // 'imgLoad'
return {
restrict: 'A',
scope: {
loadHandler: '&imgLoad' // 'imgLoad'
},
link: function (scope, element, attr) {
element.on('load', scope.loadHandler);
}
};
});
HTML:
<img img-load="onLoad()">
JSFiddle • AngularJS Guide to Isolate Scopes
While this solution is practical for most situations, it prevents you from using another directive with an isolate scope on the same element. Which brings us to…
Use $parse
to process the attributes yourself. The effect will be the same, and there won't be any conflicts with isolate scopes.
app.directive('imgLoad', ['$parse', function($parse) { // Inject $parse
return {
restrict: 'A',
link: function(scope, element, attr) {
var loadHandler = $parse(attr.imgLoad); /* Parse value of
'imgLoad' attribute */
element.on('load', function() {
loadHandler(scope); /* Run the function returned by $parse.
It needs the scope object
to operate properly. */
});
}
};
}]);
HTML (looks the same as before):
<img img-load="onLoad()">
JSFiddle • AngularJS $parse Documentation
Side Note: I didn't use ngLoad because Angular advises against it