如果图像不存在,我需要删除项目并在ng-repeat内推送下一步。
目前我正在使用next指令
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()
,则不会将下一个项目推送到数组。
这是fiddle
另一个想法是在控制器中编写函数,然后从指令运行它:
$scope.splicePost = (post) =>
$scope.posts.splice( $scope.posts.indexOf(post), 1 )
我无法理解如何做到的问题。也许需要使用隔离范围?
答案 0 :(得分:2)
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 core之外,因此当更改范围并使用$apply
或$timeout
为了使它更具可重用性,最好创建隔离范围并传入post项并将数组发布到隔离范围
的 DEMO 强>
答案 1 :(得分:0)
是的,你是正确的,你需要将数组传递给指令,如果图像无法加载,你可以从数组中拼接。使用' ='将其传递到隔离范围内,这样就可以进行双向绑定。
如果发生错误,则拼接,否则不执行任何操作。
更新: 代码:
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>
答案 2 :(得分:0)
我更愿意在组件中思考,这意味着您可以创建一个名为image-block
的组件,该组件具有您之前在标记中使用的模板。您的标记现在看起来像这样:
<div ng-controller="MyCtrl as vm">
<image-block images="vm.posts" url-property="image_url"></image-block>
</div>
您传入images
和urlProperty
,组件可以在其下找到每个图片的网址。 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
指令也需要它。该指令将捕获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));
});
}
};
});
唯一的范围属性是图像,它将被传递到父控制器以从列表中删除图像。
以下是JSFiddle的更新版本。就个人而言,我发现组件中的思维方式非常有用,它有助于将逻辑和UI细分为更小的部分。