[英]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>
您传入images
和urlProperty
在该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.