I am in the process of developing a directive that will handle scaling for child images. These images are being displayed using ng-repeat, with their URLs fetched from a REST API call made by the parent controller. Below is the code snippet for embedding the directive:
And here is the template structure for the directive:
<div>
<img image-directive-item ng-src="{{image.url}}" ng-style="{'width': {{image.width}}, 'height': {{image.height}}}" ng-if="image.done" />
</div>
To scale each image, I require information regarding the width and height of other images around it. Currently, I am trying to pass this information to the parent controller upon loading using a child directive bound to the image object. The following is the test code I am working with:
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
link: function(scope){
for(var i = 0; i < scope.images.length; i++) {
console.log(scope.images[i].width, scope.images[i].height);
}
},
templateUrl: _contextPath + 'static/html/imageDirective.html'
};
})
.directive("imageDirectiveItem", function() {
return {
link: function(scope, element) {
element.bind("load", function(e) {
scope.image.width = this.naturalWidth;
scope.image.height = this.naturalHeight;
});
}
};
});
The images are getting loaded on the page, and the load callback successfully fetches the dimensions. However, the output in the console (from the parent directive) displays "undefined undefined" for all images, along with an error message stating the inability to set the width/height to an empty value.
I prefer this approach as I need to process the images based on their DOM order. Despite this, I am facing challenges in establishing a connection between the two without resorting to what seems like temporary solutions. Any suggestions or ideas would be greatly appreciated!
The solution provided by New Dev worked perfectly for me. I modified how the element is passed to the parent directive so that it carries the necessary information from the load callback. This method taught me something new about AngularJS today!
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
controller: function($scope){
var toBeLoaded = $scope.images.length;
this.childLoaded = function(childElement) {
console.log(childElement.naturalWidth, childElement.naturalHeight);
if(--toBeLoaded == 0) {
allChildrenLoaded();
}
};
function allChildrenLoaded() {
console.log("All children loaded.");
}
},
templateUrl: _contextPath + 'static/html/imageGrid.html'
};
})
.directive("imageDirectiveItem", function() {
return {
require: "^imageDirective",
link: function(scope, element, attrs, imageDirectiveCtrl) {
element.bind("load", function() {
var e = this;
scope.$apply(function() {
imageDirectiveCtrl.childLoaded(e);
});
});
}
};
});
Check out the console output below:
414 415
507 338
366 468
432 395
500 354
507 338
414 414
478 358
507 338
All children loaded.