2

The task is to show image in template, but only if image dimensions ratio > 2

<img class="main-img" ng-if="showImage($index)" ng-src="{{item.img}}">

Function:

$scope.showImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var ratio = this.naturalWidth / this.naturalHeight;
        if (ratio > 2) {
            return true;
        } else {
            return false;
        }
    })
}

ng-if doesn't wait for image loading. How to fix? Thanks.

Seva
  • 665
  • 1
  • 7
  • 17

4 Answers4

1
<img class="main-img" ng-init="showImage($index)" ng-if="ImageLoad" ng-src="{{item.img}}">

$scope.ImageLoad=false;
$scope.showImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var ratio = this.naturalWidth / this.naturalHeight;
        if (ratio > 2) {
            $scope.ImageLoad=true;
            return true;
        } else {
            return false;
        }
    })
}

Change like this

Man Programmer
  • 5,300
  • 2
  • 21
  • 21
  • This code is wrapped by ng-repeat, so none of images will be shown if this function will return False. – Seva Sep 09 '15 at 12:21
  • ok, you can try with index **$scope.ImageLoad=[];** and inside the function set index **$scope.ImageLoad[index]=true** and in img tag set **ng-if="ImageLoad[$index]** if you have any issue let me know. – Man Programmer Sep 09 '15 at 12:25
  • you may need $timeout somewhere in there. – Quad Sep 09 '15 at 12:27
1

By running $scope.$apply() at the end of your function, you can force angular to load the images.

$scope.showImage = function(index) {
  var img = new Image();
  img.src = $scope.items[index].img;
  img.addEventListener("load", function() {
      var ratio = this.naturalWidth / this.naturalHeight;
      if (ratio > 2) {
          return true;
      } else {
          return false;
      }
   })
  $scope.apply()
}
Tyler Harden
  • 279
  • 1
  • 13
  • Yes sir, that is most direct and correct answer, just force model change. Why is this not the accepted answer? Because most programmers are "Beethoven's" at heart, and love to write symphonies for answers :). – Decoded Jun 16 '16 at 05:41
1

In the above mentioned code I believe instead of ng-if it should be 'ng-init'. If you are wrapping the code with ng-repeat none of the images will be shown as per the function you have provided. Also you can set a timeout.

Bridgit Thomas
  • 343
  • 2
  • 14
0

looks like these events are happening outside of angular's digest cycle. $apply should work but you could also forgo the event listener and bind to a function that returns false until the needed attributes are there, but those can be expensive. this approach would work too, putting load event/listening on image in a directive, then can either call a $scope method or $broadcast to manage the flag for ng-if. see this example: Image loaded event in for ng-src in AngularJS

Community
  • 1
  • 1
ron pastore
  • 270
  • 2
  • 6