【问题标题】:ng-src and onerror : Occasionally hiding a valid imageng-src 和 onerror :偶尔隐藏有效图像
【发布时间】:2016-04-20 11:09:36
【问题描述】:

为了在图像不实际存在时显示默认图像(而不是损坏的图像),我使用了这段代码:

<img ng-show="order.img" ng-src="{{order.img | fPath}}" onerror="this.style.display='none';"/>
<img ng-hide="order.img" ng-src="{{'default.png' | imgPath}}" />

这里的fPathimgPath 是在图像名称后附加前缀的过滤器。

大多数时候它运行良好(图像被渲染)。但是,在某些情况下,图像不会显示。在这种情况下,角度 sn-p 被翻译成这个 html(注意第一个 img 标签中的style="display: none;"):

<img ng-show="order.img" ng-src="http://xx.s3.amazonaws.com/o/img1.jpg" onerror="this.style.display='none'" src="http://xx.s3.amazonaws.com/o/img1.jpg" style="display: none;">
<img ng-hide="order.img" ng-src="http://xx.s3.amazonaws.com/default.png" class="ng-hide" src="http://xx.s3.amazonaws.com/default.png" style="">

问题:这可能是什么原因?以及可能的解决方法? onerror 是否比预期的更早被触发?

PS:http://xx.s3.amazonaws.com/o/img1.jpg 是一个有效的图片路径并且可用。

更新:这是定义应用程序/路由/控制器的方式

路线

t_app.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
    // ...
    $stateProvider.state('ref', {
        url: '/orders/:ref',
        templateUrl: 'views/order.htm',
        controller: 'orderController'
    });
    // ...
});

控制器

t_app.controller('orderController', ['$scope', '$stateParams', function($scope, $stateParams) {
      // Load the order (this step takes a while)
}]);

【问题讨论】:

  • 你是如何声明你的 Angular 应用和控制器的?可能是在加载控制器之前呈现了您的页面。
  • 添加了更多细节。你的第二个评论是否与onerror迟早被触发有关?
  • order 变量是远程调用加载的吗?还是它有中间值(比如,在变成“xx.s3.amazonaws.com/o/img1.jpg"”之前,“xx.s3.amazonaws.com”)
  • $scope.order 仅在远程调用后填充。直到那时它才出现。

标签: angularjs angularjs-filter onerror


【解决方案1】:

我认为你的情况是这样的:http://plnkr.co/edit/8JL0Op?p=preview

angular.module('app.helper', [])
.controller('ImgController', ['$scope', '$timeout', function($scope, $timeout) {
  $scope.img = "";
  $timeout(function(){
    $scope.img = "9c5595db-db21-4783-902a-8e80b84ae22c/6b89ed2b-878a-4f76-95c4-76ee95f47d9a.jpg";
  }, 1500);
}]);
    filter.$inject = ["$filter"];
    angular.module('app.helper').filter('addPath', filter);

    function filter($filter) {
        function filterFn(input) {
            return "http://cdn.playbuzz.com/cdn/"+input;
        }

        return filterFn;
    }

过滤器在设置order.img之前添加前缀,因此img src将(直到加载顺序)只有前缀,没有图像名称,导致错误的src。 我认为,但我不能 100% 确定,因为它只发生在某些时候,原因是有时 $scope.order 在 onerror 触发器之前(可能是在缓存结果或其他什么的时候)加载。
混合原生 javascript 和 Angular 时,很难确定执行顺序

您可以通过在过滤器中添加检查来避免这种情况:如果传递给过滤器的值为 null、未定义或空字符串,则在这种情况下返回 null。像这样的

return typeof input === "undefined" || input === null || input === "" ? null : "http://cdn.playbuzz.com/cdn/"+input;

【讨论】:

  • 感谢您的指点,您的怀疑看起来是正确的。这是 html 的样子:&lt;img onerror="console.log(this);" ng-src="http://xx.s3.amazonaws.com/o/" src="http://xx.s3.amazonaws.com/o/"&gt;。是的,我没有在过滤器中进行防御。我认为 ng-src 负责在可以评估表达式之后呈现的组件,但是有多个评估。一次当 $scope.order 为空,然后当它被填充。
  • 是的,就像您在使用 angular 时在视图中使用的其他任何东西一样,只要 angular 进行摘要,它就会被评估,同时检查值是否发生了变化。如果您更改 order.img 变量,它将再次被评估并更改图像的 src
  • 除了检查过滤器中的空值(尽管如此),您还可以设置默认 order.img 值指向透明图像或“正在加载”图像,同时等待真实图片路径
猜你喜欢
  • 1970-01-01
  • 2018-10-24
  • 2015-05-15
  • 1970-01-01
  • 2013-04-02
  • 2013-09-15
  • 2012-05-13
  • 1970-01-01
  • 2014-02-01
相关资源
最近更新 更多