【问题标题】:Error while testing image source on load in angular以角度加载时测试图像源时出错
【发布时间】:2017-08-08 09:47:08
【问题描述】:
<div class="col-xs-4 col-sm-4 col-md-4">
    {{jsonData[current].profilepic}}
    <div ng-if=IsValidImageUrl(jsonData[current].profilepic)>
        <img id="pic" ng-src="{{jsonData[current].profilepic}}"  alt=""/>
    </div>
    <div ng-if=!IsValidImageUrl(jsonData[current].profilepic)>
        <div id="pic" class="letter">
            <div class="circle">{{jsonData[current].firstName.charAt(1)+jsonData[current].lastName.charAt(1)}}</div>
        </div>
    </div>
</div>

控制器:

app.controller('task1Controller',['$scope', 'taskFactory', '$state', 'imageTestService', function($scope, taskFactory, $state, imageTestService){

    $scope.taskData = {};
    $scope.current = 0;

    taskFactory.get().then(function(response){
        $scope.jsonData = response.data.data.resultCareGivers;
    });

    $scope.IsValidImageUrl = function(url){        
        return imageTestService.IsValidImageUrl(url); //Error here
    };

    $scope.viewDetails = function(){
        $state.go('view-details', {details: $scope.jsonData[$scope.current]});
    };


    $scope.back = function(){
        $scope.current = ($scope.current !== 0 ? $scope.current - 1 : 0);
    };

    $scope.next = function(){
        $scope.current = ($scope.current !== $scope.jsonData.length-1 ? $scope.current + 1 : $scope.jsonData.length-1);
    };

}]);

图像测试服务:

app.service('imageTestService', function($q){

    this.IsValidImageUrl = function(url){
        var deferred = $q.defer();
        if(url != null && url != ""){
            var img = new Image();
            img.onerror = function() { deferred.resolve(false); };
            img.onload =  function() { deferred.resolve(true); };
            img.src = url;
            return deferred.promise;
        }
    };

});

控制台中的错误堆栈:

Error link

达到 10 次 $digest() 迭代。中止! 观察者在最后 5 次迭代中触发: [[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal" :{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{" status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal" :{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[当前].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[ {"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"状态":0}}}]]

更新 2:

app.service('imageTestService', function(){

    this.IsValidImageUrl = function(url){
        var result = {};
        if(url != null && url != ""){
            var img = new Image();
            img.onerror = function() { result.val = true };
            img.onload =  function() { result.val = false };
            return result;
        }
    };
});

但在控制台中仍然出现同样的错误。

更新 3:

app.service('imageTestService', function(){

    this.IsValidImageUrl = function(url){
        var result = {
            val :false
        };
        this.img = new Image();
        this.img.onabort = function() { result.val = false };
        this.img.onerror = function() { result.val = false };
        this.img.onload =  function() { result.val = true };
        return result.val;
    };
});

在更新 3 中,无论我做什么,总是会调用 image.onabort()

它在函数调用本身抛出错误fails to load resource

$scope.IsValidImageUrl = function(url){    //Failed to load resource error    
   return imageTestService.IsValidImageUrl(url); 
};

【问题讨论】:

  • 你有什么问题?
  • 你为什么在服务中使用 $q?
  • Vivz 是对的,你应该在 IsValidImageUrl 函数中返回布尔值。
  • @GauravSrivastava 我如何返回布尔值。我认为 image.onerror 或 image.onload 是异步的

标签: javascript angularjs


【解决方案1】:

简答

为了摆脱这个错误,我们需要 IsValidImageUrl() 方法应该返回显式结果的情况。

例如你可以用默认值false初始化result

 this.IsValidImageUrl = function(url){
    var result = {
      val:false
    };
    if(url != null && url != ""){
        var img = new Image();
        img.onerror = function() { result.val = true };
        img.onload =  function() { result.val = false };
        return result.val;
    }
};

Demo with 10 $digest() iterations reached error

fixed Demo


长答案

首先让我们了解为什么我们会得到10 $digest() iterations reached. Aborting!。一般来说,它是 Angular 的一个守卫,可以摆脱会导致内存泄漏和最后页面卡住的无限循环的摘要循环。

在我们的例子中,一旦IsValidImageUrl 将返回不同的结果,Angular 将触发新的摘要循环等等 - 这将导致上述错误。


ng-if 调用方法不是一个好习惯 | ng-show/hide | ng-style .... - 它过度杀戮,会影响您的页面性能。

我建议您从控制器调用IsValidImageUrl(jsonData[current].profilepic) 并将其存储在某个地方。对于ng-if,我们只需要布尔值。

仅供参考,Image.onloadImage.onError 是回调,因此您首先返回空对象 result 并在延迟一段时间后使用 Image.onloadImage.onError 更新 result 内容,这将触发新的摘要循环导致额外调用 IsValidImageUrl()`。

ngIf 指令是一个监听器,它监听result,10 次循环后将抛出 10 $digest() iterations reached. Aborting! 异常。


【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-02-23
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2019-07-24
  • 1970-01-01
相关资源
最近更新 更多