I would rather think in components, means you could create a component called image-block which has the template you used in your markup before. Your markup now could look like this:
<div ng-controller="MyCtrl as vm">
<image-block images="vm.posts" url-property="image_url"></image-block>
</div>
You pass in the images and the urlProperty under which the component can find the url for each image. The image-block directive is implemented as follows:
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);
}
};
}]
};
});
The component has its own controller for logic, which also gets required by the isImage directive. This directive will catch the error event and calls the removeImage function of the parent controller.
The isImage directive looks like this:
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));
});
}
};
});
The only scope property is the image, which will be passed along to the parent controller to remove the image from the list.
Here is an updated version of your JSFiddle. Personally I find the way of thinking in components very useful and it helps to break down your logic and UI into smaller pieces.