簡體   English   中英

angular-如果src錯誤,則在指令內部拼接數組

[英]angular - splice array inside directive if src error

如果圖像不存在,我需要刪除項目並在ng-repeat中推送下一個。

目前我正在使用下一條指令

myApp.directive("noImage", function() {
  return {
    link: function(scope, element, attrs) {
      return element.bind("error", function() {
        element.attr("src", attrs.noImage);
        return element.addClass('no-img');
        //return element.parent().remove();
        //return element.parent().splice();
      });
    }
  };
});

顯然,如果使用element.parent().remove()splice() ,則不會將下一項推入數組。

這是小提琴

另一個想法是在控制器中寫入函數,然后從指令運行它:

$scope.splicePost = (post) =>
  $scope.posts.splice( $scope.posts.indexOf(post), 1 )

我無法做到這一點的問題。 也許需要使用隔離范圍?

ng-repeat為轉發器中的每個項目創建一個子范圍。

這意味着在指令內,您將繼承父作用域數組,並可以訪問每個發布項目的scope.post

myApp.directive("noImage", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("error", function () {
                // get index of post in the posts array
                var idx = scope.posts.indexOf(scope.post);
                scope.$apply(function () {
                    // splice posts array
                    scope.posts.splice(idx, 1);
                });
            });
        }
    };
});

由於該事件不在angular核心之外,因此您需要告訴angular在更改范圍時運行摘要,這可以使用$apply$timeout

為了使其更可重用,最好創建隔離的作用域並將post項目和post數組傳遞給隔離的作用域

演示

是的,您是正確的,您需要將數組傳遞到指令中,如果無法加載映像,則可以從數組中進行拼接。 用'='在孤立的范圍內傳遞它,所以您有兩種方式綁定。

如果發生錯誤,請進行拼接,否則,什么也不做。

更新:代碼:

var myApp = angular.module('myApp',[]);

myApp.directive("noImage", function() {
  return {
    scope: {
      posts: "="
    },
    link: function(scope, element, attrs) {
      return element.bind("error", function() {
        scope.posts.splice(scope.$parent.$index, 1);
        scope.$apply();
      });
    }
  };
});

該html將變為:

<div ng-controller="MyCtrl">
  <ul>
     <li ng-repeat = 'post in posts | limitTo: 5'>
         <img posts="posts" ng-src = "{{post.image_url}}" no-image = "" />

     </li>
  </ul> 
</div>

我寧願想到組件,這意味着您可以創建一個名為image-block組件,該組件具有之前在標記中使用的模板。 您的標記現在可能如下所示:

<div ng-controller="MyCtrl as vm">
  <image-block images="vm.posts" url-property="image_url"></image-block>
</div>

您傳入imagesurlProperty在該urlProperty下組件可以找到每個圖像的url。 image-block指令的實現如下:

myApp.directive("imageBlock", function() {
  return {
    restrict: 'E',
    scope: {
      images: '=',
      urlProperty: '@',
      limit: '@'
    },
    template:
      '<ul>' +
        '<li ng-repeat="image in images | limitTo: limit || 3">' + 
          '<img ng-src="{{ image[urlProperty] }}" is-image="image" />' +
        '</li>' +
      '</ul>',
    controller: ['$scope', function(scope) {
        this.removeImage = function(image) {
            var index = scope.images.indexOf(image);
            if(index > 0) {
                scope.images.splice(index, 1);
            }
        };
    }]
  };
});

該組件具有自己的邏輯控制器, isImage指令也需要該isImage 該指令將捕獲error事件並調用父控制器的removeImage函數。

isImage指令如下所示:

myApp.directive("isImage", function() {
  return {
    scope: {
        image: '=isImage'    
    },
    require: '^imageBlock',
    link: function(scope, element, attrs, ctrl) {
      return element.bind("error", function() {
         scope.$apply(ctrl.removeImage(scope.image));
      });
    }
  };
});

唯一的scope屬性是圖像,它將被傳遞到父控制器以從列表中刪除圖像。

這是JSFiddle的更新版本。 我個人認為組件的思維方式非常有用,它有助於將邏輯和UI分解為更小的部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM