Erzwingen eines ng-src-Neuladens

77

Wie kann ich anglejs zwingen, ein Bild mit einem ng-src-Attribut neu zu laden, wenn sich die URL des Bildes nicht geändert hat, der Inhalt jedoch?

<div ng-controller='ctrl'>
    <img ng-src="{{urlprofilephoto}}">
</div>

Ein uploadReplace-Dienst, der einen Datei-Upload durchführt, ersetzt den Inhalt des Bildes, nicht jedoch die URL.

app.factory('R4aFact', ['$http', '$q', '$route', '$window', '$rootScope',
function($http, $q, $route, $window, $rootScope) {
    return {
        uploadReplace: function(imgfile, profileid) {
            var xhr = new XMLHttpRequest(),
                fd = new FormData(),
                d = $q.defer();
            fd.append('profileid', profileid);
            fd.append('filedata', imgfile);
            xhr.onload = function(ev) {
                var data = JSON.parse(this.responseText);
                $rootScope.$apply(function(){
                    if (data.status == 'OK') {
                        d.resolve(data);
                    } else {
                        d.reject(data);
                    }
                });
            }
            xhr.open('post', '/profile/replacePhoto', true)
            xhr.send(fd)
            return d.promise;
        }
    }
}]);

Wenn der uploadReplace zurückkehrt, weiß ich nicht, wie ich das Neuladen des Bildes erzwingen kann

app.controller('ctrl', ['$scope', 'R4aFact', function($scope, R4aFact){
    $scope.clickReplace = function() {
        R4aFact.uploadReplace($scope.imgfile, $scope.pid).then(function(){
            // ??  here I need to force to reload the imgsrc 
        })
    }
}])
Ruben Decrop
quelle
Set urlprofilephotoleer und setzen Sie es wieder auf die URL.
Chandermani
Kann mit sein $scope.$apply?
Ivan Chernykh
Wenn Sie die URL leer machen und dann erneut festlegen, wird eine falsche Anfrage an den Server gesendet, die vermieden werden sollte. Der $ scope. $ Apply ist nicht das Problem. Der Anser der Factory-Funktion befindet sich bereits in $ rootScope. $
Apply

Antworten:

77

Eine einfache Problemumgehung besteht darin, einen eindeutigen Zeitstempel an ng-src anzuhängen, um das erneute Laden von Bildern wie folgt zu erzwingen:

$scope.$apply(function () {
    $scope.imageUrl = $scope.imageUrl + '?' + new Date().getTime();
});

oder

angular.module('ngSrcDemo', [])
    .controller('AppCtrl', ['$scope', function ($scope) {
    $scope.app = {
        imageUrl: "http://example.com/img.png"
    };
    var random = (new Date()).toString();
    $scope.imageSource = $scope.app.imageUrl + "?cb=" + random;
}]);
user225088
quelle
1
$ scope.imageUrl + = '?' + Date.now ();
Heychez
28

Vielleicht könnte es so einfach sein, der Bild-URL eine Decache-Abfragezeichenfolge hinzuzufügen? dh.

var imageUrl = 'http://i.imgur.com/SVFyXFX.jpg';
$scope.decachedImageUrl = imageUrl + '?decache=' + Math.random();

Dies sollte das Neuladen erzwingen.

Philip Bulley
quelle
16

Ein "Winkelansatz" könnte darin bestehen, einen eigenen Filter zu erstellen, um der Bild-URL einen zufälligen Querystring-Parameter hinzuzufügen.

Etwas wie das:

.filter("randomSrc", function () {
    return function (input) {
        if (input) {
            var sep = input.indexOf("?") != -1 ? "&" : "?";
            return input + sep + "r=" + Math.round(Math.random() * 999999);
        }
    }
})

Dann können Sie es so verwenden:

<img ng-src="{{yourImageUrl | randomSrc}}" />

acromm
quelle
6

Versuche dies

app.controller('ctrl', ['$scope', 'R4aFact', function($scope, R4aFact){
$scope.clickReplace = function() {
    R4aFact.uploadReplace($scope.imgfile, $scope.pid).then(function(response){
        $scope.urlprofilephoto  = response + "?" + new Date().getTime(); //here response is ur image name with path.
    });
}
 }])
Nitish Kumar
quelle
0

Ich habe eine Direktive erstellt, um zufällige Parameter in den src einzufügen, aber nur, wenn sich das Bild ändert, damit ich nicht so viel mit dem Caching zu tun habe.

Ich verwende es, um das Profilbild des Benutzers in der Navigationsleiste zu aktualisieren, wenn er es über AJAX aktualisiert, was nicht so oft vorkommt.

(function() {
  "use strict";

  angular
    .module("exampleApp", [])
    .directive("eaImgSrc", directiveConstructor);

  function directiveConstructor() {
    return { link: link };

    function link(scope, element, attrs) {
      scope.$watch(attrs.eaImgSrc, function(currentSrc, oldSrc) {
        if (currentSrc) {
          // check currentSrc is not a data url,
          // since you can't append a param to that
          if (oldSrc && !currentSrc.match(/^data/)) {
            setSrc(currentSrc + "?=" + new Date().getTime());
          } else {
            setSrc(currentSrc);
          }
        } else {
          setSrc(null);
        }
      })

      function setSrc(src) { element[0].src = src; }
    }
  }
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="exampleApp">
  <div>
    <img ea-img-src="src"></img>
  </div>

  <button ng-click="src = 'http://placehold.it/100x100/FF0000'">IMG 1</button>
  <button ng-click="src = 'http://placehold.it/100x100/0000FF'">IMG 2</button>
  <button ng-click="src = 'http://placehold.it/100x100/00FF00'">IMG 3</button>
</div>

Nicooga
quelle