仅当其嵌套图像存在时,如何在 AngularJS ng-repeat 循环中显示对象?

How to show the object in an AngularJS ng-repeat loop, only if its nested image exists?

我的 AngulaJS 驱动的前端从本地 JSON 文件获取数据,稍后将切换到 API。数据是 Project 个对象的列表,其中包含 Image 个对象的嵌套列表。我循环显示此数据:

<div id="projects" ng-app="portfolio">
    <div id="projectsList" ng-controller="ProjectsListController as projectsList">
        <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects">
            <div class="project-image">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>
</div>

但有时图像src无效(错误404)。最好跳过这样的项目,因为找不到第一张图片 (images[0])。如何让脚本跳过不相关的对象?


编辑

我已经得到了三个答案,但解决方案不起作用,我想准确解释问题:

图片的src属性总是设置的。 不是的问题。这意味着,检查它是否已设置(如 ng-show="projectItem._embedded.images[0].src != ''"ng-if="{{projectItem._embedded.images[0].src}}")将 工作——不能工作。

它不起作用 -- src 属性 已设置。这是错误的(会引起 404 错误),但它已设置并且 projectItem._embedded.images[0].src != '' 也会对 "irrelevant" 对象 return true

您可以使用 ng-if

<div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects" ng-if="{{projectItem._embedded.images[0].src}}">
            <div class="project-image">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>

或者您也可以使用 ng-show/ng-hide,它只是不显示元素,但会出现在 DOM 中。

但是当你使用 ng-if 时要小心,因为它会创建自己的作用域。

编辑: 如果 url 已经设置,那么一种方法是使用此方法(或类似方法)测试 url 是否存在JavaScript/jQuery check broken links
ng-if="UrlExists(projectItem._embedded.images[0].src)"

        <div class="project-image" ng-if="projectItem._embedded.images[0].src != ''">
            <img
                ng-src="{{projectItem._embedded.images[0].src}}"
                title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
            />
        </div>

这是完成这项工作的一种 hacky 方式:

为避免在图像抛出 404 错误或图像无效时加载图像,

这必须在您的控制器内。此函数检查图像 URL 是否为 valid/invalid.

$scope.imageExists = function(image, object, index) {
    var img = new Image();
    img.onload = function() {
      object[index] = true;
      $scope.$apply();
    }; 
    img.onerror = function() {
      return false;
    };
    img.src = image;
 };

现在在视图中:

我正在 ng-repeat 中启动一个名为 img={}; 的对象。

然后将 ng-repeat 中该索引的值初始化为 $scope.imageExists 函数。在该函数内部,在该图像加载成功时,我正在设置 img[index]= true.

<div ng-repeat="image in images" ng-init="img = {}">
   <img ng-src="{{image}}" ng-init="img[$index] = imageExists(image, img, $index)" ng-show="img[$index]">
</div>

DEMO

所以将它应用到您的代码中:

<div id="projects" ng-app="portfolio">
    <div id="projectsList" ng-controller="ProjectsListController as projectsList">
        <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects"  ng-init="img = {}">
            <div class="project-image" ng-init="img[$index] = imageExists(projectItem._embedded.images[0].src, img, $index)" ng-show="img[$index]">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>
</div>

将上面的 $scope.imageExists 代码放入您的控制器。

您可以创建自己的图像指令:

<my-image src="http://someimageurl"></my-image>

如果图像存在,指令会将图像插入到DOM。如果没有,那么您可以忽略它,或者插入一条消息。

var app = angular.module('app', []);
app.directive('myImage', function() {
  return {
    restrict: 'E',
    replace:true,
    link: function(scope, element, attr) {
      var image = new Image();
      image.onload = function() {
         element.append(image);
      }
      image.onerror = function() {
         element.html('Something went wrong or the image does not exist...');
      }
      image.src = attr.src;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <my-image src="https://www.google.ca/images/srpr/logo11w.png" />
  
  <my-image src="https://server/images/doesnotexist.png" />
</div>