删除图像或将图像添加到集合后,无法让 bxslider 正确重新加载

Can't get bxslider to reload properly after removing or adding an image to the collection

我 运行 遇到了一些问题(呃.. 否则我不会在这里)。我已经尽我所能用谷歌搜索,但无法弄清楚为什么它不起作用。我已经尝试了很多东西,所以系好安全带并为大量代码块做好准备。

目前的情况:

这是我的 bxslider 的代码:

<ul class="bx-slider" bx-slider>
    <li class="slide frame fluid image" ng-repeat="img in sliderImages track by $index" notify-when-repeat-finished width="400px" height="225px">
         <a id="reload-slider" class="huge red corner label" ng-click="deleteItem($index)">
             <i class="remove icon"></i>
         </a>
         <img class="image centered" ng-src="../{{img}}"/>
     </li>
 </ul>

正如您可能猜到的那样,我已经将 jquery 插件变成了一个指令,并且还制作了一个在 ng-repeat 完成时广播的指令:

BxSlider 指令:

module.directive('bxSlider', [function () {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        //console.log(element);
        scope.$on('repeatFinished', function () {
            console.log("ngRepeat has finished");
            element.bxSlider().bxSlider(scope.$eval('{' + attrs.bxSlider + '}'));
        });
        scope.$on('reload-slider', function() {
            console.log("TEXTS!");
            element.reloadSlider();
        });
    }
}
}]);

Ng-重复完成指令:

module.directive('notifyWhenRepeatFinished', ['$timeout', function ($timeout) {
return {
    restrict: 'A',
    link: function (scope, element, attr) {
        if (scope.$last === true) {
            $timeout(function () {
                scope.$emit('repeatFinished');
            });
        }
    }
}
}]);

当你点击右上角的叉号时,通过这个功能删除图片:

删除图片功能

 $scope.deleteItem = function(index){
    alert('deleting item: ' + $scope.sliderImages[index]);
    $http({method: 'POST', url: '/guta/API/slides/'+ index}).then(function(result) {
        console.log("Okay.. I finished the post.");
        console.log("Slider images old:", $scope.sliderImages);

        $scope.sliderImages.splice(index, 1);
        console.log("Slider images new:", $scope.sliderImages);
        $scope.$broadcast('reload-slider');
    });
};

如您所见,我尝试将 reload-slider 广播到指令并让元素自行重新加载。据我所知,广播应该触发

scope.$on('reload-slider', function(){...}

问题:

console.log 有效,但它根本不会重新加载滑块,图像数组不会重新循环,什么也没有。它唯一做的就是记录 "TEXTS" 并将文件扔到服务器上(它应该这样做)

删除后应该不会显示图片

感谢任何帮助、修复或想法。

所以,一位同事帮我解决了这个问题,这是工作位。

BoxSlider 本身:

<ul class="bx-slider" bx-slider="mode: 'horizontal', controls:false">
    <li class="slide frame fluid image" ng-repeat="img in sliderImages|ngRepeatFinish) track by $index" width="400px" height="225px">
        <a id="reload-slider" class="huge red corner label" ng-click="deleteItem($index)">
            <i class="remove icon"></i>
        </a>
        <img class="image centered" ng-src="../{{img}}"/>
    </li>
</ul>

指令:

module.directive('bxSlider', ['$rootScope',function ($rootScope) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var slider = element;
        $rootScope.$on('ngRepeatFinished', function() {
            console.log("repeat finished!!");
            console.log(element);
            if(element.reloadSlider){
                element.reloadSlider();
            }
            else{
                element.bxSlider().bxSlider(scope.$eval('{' + attrs.bxSlider + '}'));
            }

        });
    }
}
}]);

这个过滤器会在ng-repeat结束时调用

module.filter('ngRepeatFinish', function($timeout, $rootScope){
return function(data){
    var me = this;
    var flagProperty = '__finishedRendering__';
    if(!data[flagProperty]){
        Object.defineProperty(
            data,
            flagProperty,
            {enumerable:false, configurable:true, writable: false, value:{}});
        $timeout(function(){
            delete data[flagProperty];
            $rootScope.$broadcast('ngRepeatFinished');
        },0,false);
    }
    return data;
};
});

控制器中点击叉号时调用的函数:

$scope.deleteItem = function(index){
    alert('deleting item: ' + $scope.sliderImages[index]);
    $http({method: 'POST', url: '/guta/API/slides/'+ index}).then(function(result) {
        $scope.sliderImages.splice(index, 1);
    });

};

所以,我将尝试解释代码运行的顺序:

  1. bxSlider 在循环完成后加载(这是通过过滤器上的广播学习的)
  2. 用户点击图片角上的叉号he/she 想要删除
  3. 跟踪每个图像的 $index 被发送到函数,该函数将 post 图像 url 发送到服务器并请求删除
  4. 要删除的图片从服务器上移除,前端使用splice()移除图片(不需要重新请求)
  5. (我认为)因为 ng-repeat 的数组被更改,它再次运行。
  6. ng-repeat结束后,filter再次调用
  7. 因为函数 element.reloadSlider 是可用的(不是未定义的)它调用 element.reloadSlider();而不是重新初始化整个 boxslider,这将导致丑陋的 bxslider。

如果你仔细查看 bx-slider 属性,你会看到传入了两个配置选项 (bx-slider="mode: 'horizontal', controls:false") 特别是 Controls:false 很重要,这可以防止每个图像都有自己的自己的一组上一个和下一个按钮,但只允许 bx-slider 本身有那些

我希望这能帮助那些卡在 angular bx-slider 上的人。