angular js '?' in ng-src causes infinite l

2019-07-18 11:02发布

问题:

I am trying to get a way around IE getting images from cache while using AngularJS

I have this following code

<img ng-src="./individuals/image/{{team._id}}/{{member._id}}{{getRandom()}}" >

In the controller

$scope.getRandom=function(){
        return "?ran="+new Date().getTime()+"";
}

When I run, I get this error

Error: 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [["fn: function (a){\n\"use strict\";\ntry{for(var b=0,c=q,g;b<c;b++){if(typeof(g=l[b])==\"function\")g=g(a),g==null||g==s?g=\"\":typeof g!=\"string\"&&(g=da(g));B[b]=g}return B.join(\"\")}catch(f){d(Error(\"Error while interpolating: \"+e+\"\\n\"+f.toString()))}}; newVal: \"./individuals/image/51c209ead8b8d863ad69de97/51c209ead8b8d863ad69de65?ran=1371757784485\"; oldVal: \"./individuals/image/51c209ead8b8d863ad69de97/51c209ead8b8d863ad69de65?ran=1371757784457\"","fn: function (a){\n\"use strict\";\ntry{for(var b=0,c=q,g;b<c;b++){if(typeof(g=l[b])==\"function\")g=g(a),g==null||g==s?g=\"\":typeof g!=\"string\"&&(g=da(g));B[b]=g}return B.join(\"\")}catch(f){d(Error(\"Error while interpolating: \"+e+\"\\n\"+f.toString()))}}; newVal: \"./individuals/image/51c209ead8b8d863ad69de97/51c209ead8b8d863ad69dec9?ran=1371757784487\"; oldVal: \"./individuals/image/51c209ead8b8d863ad69de97/51c209ead8b8d863ad69dec9?ran=1371757784459\"","fn: function (a){\n\"use strict\";\ntry{for(var b=0,c=q,g;b<c;b++){if(typeof(g=l[b])==\"function\")g=g(a),g==null||g==s?g=\"\":typeof g!=\"string\"&&(g=da(g));B[b]=g}return B.join(\"\")}catch(f){d(Error(\"Error while interpolating: \"+e+\"\\n\"+f.toString()))}}; newVal: \"./individuals/image/51c209ead8b8d863ad6

If I remove the {{getRandom()}} it works fine.

Please help.. Thanks in advance

UPDATE: Please find below the changes to controller that fixed the issue. Thanks to the answer from Liviu T.

$scope.lastMillis = new Date().getTime();
    $scope.getRandom=function(){
        var curMillis = new Date().getTime();
        if (curMillis-$scope.lastMillis>5000) {
            $scope.lastMillis = curMillis;
        }
        return "?ran="+$scope.lastMillis;
    }

回答1:

Well I think the problem is the getRandom function returning a different value every time it's called. Here's what happens:

  1. Angular call your function
  2. Gets the value
  3. See's it's different from the previous value
  4. Marks the cycle as dirty
  5. After the cycle is finished it re-runs the cycle thus getting a new value ...

The idea would be to have getRandom give discreet values over a period of time. For example only give a new value every 1, 10, 30 sec whatever you see fit.

This advice applies to many things, actually. Angular provides no guarantees about how many times it will call your functions that are found in bindings. So you need to make them fast and also you need to make sure that for the same input they return the same output(most times, though in this case it might be justified).

Also consider exactly when/how the image might change and if the actual changes can be triggered by something else consider only creating a new result value for getRandom only when the actual changes are triggered(ex: user uploads a new profile image, a timer executes, etc)

UPDATE: Can't replicate it in plunker using Chrome