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 
        })
    }
}])

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;
}]);

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.


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}}" />


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.
    });
}
 }])

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.