加载 Ng-Repeat 元素后运行的 jQuery Swiper 脚本

2024-04-16

我正在使用 AngularJS、jQuery、HTML、CSS 和 Bootstrap 制作一个 Web 应用程序,我想从位于 Apache2 服务器中的 JSON 中选择一些图像链接,并使用它们在我的主页中呈现这些图像。我还想像在旋转木马上一样滑动它们。为了做到这一点,我正在尝试使用iDangero.us Swiper http://www.idangero.us/swiper/#.VogP2RUrKUk.

当我选择具有 3 个独立 div 的图像时,没有任何问题。我得到我的图像,然后我可以正常地根据需要滑动它们。我这样做如下所示:

主要.html:

<div ng-init="initGetRequestMain()">

  <div class="swiper-slide" ng-click="swipers()" 
              style="{{data.background1}}"></div>
  <div class="swiper-slide" ng-click="swipers()" 
              style="{{data.background2}}"></div>
  <div class="swiper-slide" ng-click="swipers()" 
              style="{{data.background3}}"></div>

   <script src="scripts/custom/main/swipers.js"></script>
</div>

我使用 Swiper 从一张图像滑动到另一张图像,它似乎可以正常工作。这是一个 jQuery 插件,您可以在以下位置查看一些演示这个链接 http://www.idangero.us/swiper/demos/#.VWsOY8_tlBc.

Swipers.js:

angular.module('swipers', [])
       .controller('',[ 
        $(document).ready(function (){
           var swiper = new Swiper('.swiper-container',{
           direction: 'horizontal',
           pagination: '.swiper-pagination',
           paginationClickable: true
       })
})]);

Json:

"background1":"background-image: url(images/img1.jpg)",
"background2":"background-image: url(images/img2.jpg)",
"background3":"background-image: url(images/img3.jpg)"

主控制器.js:

  myApp.controller('MainController', ["$scope","$http",                
                  function($scope,$http){

      $scope.initGetRequestMain = function(){

       $http.get('http://localhost/main.json').success(function(data){

         $scope.data=data;
       })
      }
  }]);

问题是当我尝试使用ng-repeat我再也看不到它们,而不是 3 个独立的 div,而且我的 Swiper 脚本会在它们完全加载之前触发。我的控制台或 JSON 中没有错误(使用 JSONLint 验证)。下面,我添加了这两种情况下输出的 2 个屏幕截图。

使用 3 个独立的 div:

不与 ng-repeat 一起使用:

这是我尝试制作的代码ng-repeat保持与以前相同的控制器和相同的 Swiper 脚本:

主要.html:

  <div ng-init="initGetRequestMain()">

       <div ng-repeat="slide in data.slides" isLoaded="">
           <div class="swiper-slide" style="{{slide.background}}" 
                       ng-click="swipers()"></div>
       </div>

    <script type="text/javascript-lazy" src="scripts/custom/main/swipers.js"></script>
  </div>

mainJson.json:

"slides":[
            {"background":"background-image:url('images/img1.jpg')"},
            {"background":"background-image:url('images/img2.jpg')"},
            {"background":"background-image: url('images/img3.jpg')"}
],

为了在触发脚本之前加载图像,我尝试使用 2 个自定义指令。

isLoaded告诉我最后一次是什么时候ng-repeat元素已加载并设置pageIsLoaded = true;:

myApp.directive('isLoaded', function (){

   return{
     scope:true,
     restrict: 'A', //Attribute type
     link: function (scope, elements, arguments){ 

        if (scope.$last === true) {
            scope.pageIsReady = true;
            console.log('page Is Ready!');
         }
     }   
   }
})

gettingTheScript等待pageIsLoaded = true;并加载脚本:

myApp.directive('src', function (){

     return{
       scope:true,
       restrict: 'A', //Attribute type
       link: function (scope, elements, arguments){

            scope.$on(pageIsReady===true, function(){
                   if (attr.type === 'text/javascript-lazy'){

                       scope.scriptLink = arguments.src;
                    }
             })
         },
         replace: true, //replaces our element 
         template: '{{scriptLink}}'
       }
  })   

他们似乎没有解决我的问题。我也看不到console.log('page Is Ready!');做第一个的时候。

当我必须在页面加载后触发像 Swiper 这样的脚本以避免此类问题时,我遇到了一些麻烦。我的图像似乎没有高度。我认为问题是由ng-repeat在触发我的脚本之前未完全加载。

我究竟做错了什么?有更好的解决方案吗?


在讨论如何实现这项工作之前,大多数此类 jQuery 插件都不能很好地与 Angular 配合使用,因为它们对 Angular 不知道的 DOM 进行了修改。

话虽这么说,技巧是将 jQuery 插件的调用推迟到 Angular 渲染 DOM 之后。

首先,将您的 swiper 插件放入指令中:

.directive('swiper', function($timeout) {
    return {
        link: function(scope, element, attr) {
            //Option 1 - on ng-repeat change notification
            scope.$on('content-changed', function() {
                new Swiper(element , {
                    direction: 'horizontal',
                    pagination: '.swiper-pagination',
                    paginationClickable: true);
            }
            //Option 2 - using $timeout
            $timeout(function(){
                new Swiper(element , {
                    direction: 'horizontal',
                    pagination: '.swiper-pagination',
                    paginationClickable: true);
            });

        }
    };
})

对于选项 1,您需要修改 isLoaded 指令

myApp.directive('isLoaded', function (){

   return{
     scope:false, //don't need a new scope
     restrict: 'A', //Attribute type
     link: function (scope, elements, arguments){ 

        if (scope.$last) {
            scope.$emit('content-changed');
            console.log('page Is Ready!');
        }
     }   
   }
})

最后,您的标记(请注意从 isLoaded 到 is-loaded 的更改...这可能是您没有看到通知的原因)。

<div ng-init="initGetRequestMain()" swiper>

   <div ng-repeat="slide in data.slides" is-loaded>
       <div class="swiper-slide" style="{{slide.background}}" 
                   ng-click="swipers()"></div>
   </div>
</div>

如前所述,大多数具有轮播功能的 jQuery 插件不能很好地处理 DOM 的更改(即新元素)。即使使用这两个选项,如果在首次渲染 ng-repeat 后更改模型,您可能会看到意外的情况。但是,如果您的模型是静态的,这应该适合您。如果您的模型发生变化,那么您可能需要搜索更“有角度”的轮播指令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

加载 Ng-Repeat 元素后运行的 jQuery Swiper 脚本 的相关文章