$timeout服务未从指令更新角度控制器



"use strict";
angular.module("appBanner", [])
  .controller('bannerCtrl', function($scope) {
     $scope.slides = ["auto", "boatowners", "commercial"];
		$scope.currentIndex = 0;
        $scope.setCurrentSlideIndex = function (index) {
            $scope.currentIndex = index;
			$scope.currentSlideIndex = $scope.slides[$scope.currentIndex];
        }
        $scope.isCurrentSlideIndex = function (index) {
            return $scope.currentIndex === index;
        };
        $scope.prevSlide = function () {
			$scope.currentIndex = ($scope.currentIndex > 0) ? --$scope.currentIndex : $scope.slides.length - 1;
			$scope.setCurrentSlideIndex($scope.currentIndex);
        };
        $scope.nextSlide = function () {
           $scope.currentIndex = ($scope.currentIndex < $scope.slides.length - 1) ? ++$scope.currentIndex : 0;
		   $scope.setCurrentSlideIndex($scope.currentIndex);
        };
  })
  .directive('banner', function($timeout) {
    return {
     
      link: function postLink(scope, element, attrs) {
        var progressBar = angular.element(".progress");
        var bannerNav = angular.element(".bannerNav");
        var navCircle = angular.element(".bannerNav.navCircle");
        var imgSlides = angular.element(".imgSlide");
        var slideTime = 1.5;
        TweenMax.set(imgSlides, {
          autoAlpha: 0,
          display: "none"
        });
        TweenMax.set(progressBar, {
          autoAlpha: 0
        });
        var tlMaster = initMasterTimeline(imgSlides, progressBar, slideTime);
        scope.getWidth = function() {
          return $(element).width();
        };
        scope.play = function(newIndexValue) {
          tlMaster.play(newIndexValue);
        };
        scope.$watch('slideshowHover', function(newValue) {
          if (newValue === true) TweenMax.to(bannerNav, 0.5, {
            autoAlpha: 0.85
          })
          else TweenMax.to(bannerNav, 0.5, {
            autoAlpha: 0.25
          })
        });
        scope.$watch('currentSlideIndex', function(newIndexValue) {
          scope.play(newIndexValue);
        });
        scope.$watch(scope.getWidth, function(width) {
          element.css('height', width * 0.4);
        });
        function updateCurrentIndex(index) {
          $timeout(function() {
            scope.setCurrentSlideIndex(index);
          });
        }
        function setProgress(timeline, progressBar) {
          TweenMax.set(progressBar, {
            scaleX: timeline.progress()
          });
        }
        function initMasterTimeline(imgSlides, progressBar, slideTime) {
          var tlAuto = initAutoTimeline(imgSlides, progressBar, slideTime);
          var tlBoatowners = initBoatownersTimeline(imgSlides, progressBar, slideTime);
          var tlCommercial = initCommercialTimeline(imgSlides, progressBar, slideTime);
          var tlMaster = new TimelineMax({
            repeat: -1
          });
          tlMaster.set(progressBar, {
              scaleX: 0,
              transformOrigin: "left"
            })
            .add(tlAuto, "auto")
            .add(tlBoatowners, "boatowners")
            .add(tlCommercial, "commercial");
          return tlMaster;
        }
        function initAutoTimeline(imgSlides, progressBar, slideTime) {
          var stayTime = 10; //for now, can make each timeline as long as you want later
          var tlAuto = new TimelineLite({
            onUpdate: setProgress,
            onUpdateParams: ["{self}", progressBar]
          });
          var autoNavCircle = $(".navCircle")[0];
          tlAuto.set(imgSlides[0], {
              display: "block"
            })
            .to(progressBar, slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[0], slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[0], slideTime, {
              autoAlpha: 0
            }, stayTime)
            .to(progressBar, slideTime, {
              autoAlpha: 0
            }, stayTime)
            .set(imgSlides[0], {
              display: "none",
              onComplete: updateCurrentIndex(1)
            })
          return tlAuto;
        }
        function initBoatownersTimeline(imgSlides, progressBar, slideTime) {
          var stayTime = 10; //for now, can make each timeline as long as you want later
          var tlBoatowners = new TimelineLite({
            onUpdate: setProgress,
            onUpdateParams: ["{self}", progressBar]
          });
          var boatownersNavCircle = $(".navCircle")[1];
          tlBoatowners.set(imgSlides[1], {
              display: "block"
            })
            .to(progressBar, slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[1], slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[1], slideTime, {
              autoAlpha: 0
            }, stayTime)
            .to(progressBar, slideTime, {
              autoAlpha: 0
            }, stayTime)
            .set(imgSlides[1], {
              display: "none",
              onComplete: updateCurrentIndex(2)
            });
          return tlBoatowners;
        }
        function initCommercialTimeline(imgSlides, progressBar, slideTime) {
          var stayTime = 10; //for now, can make each timeline as long as you want later
          var tlCommercial = new TimelineLite({
            onUpdate: setProgress,
            onUpdateParams: ["{self}", progressBar]
          });
          var commercialNavCircle = $(".navCircle")[2];
          tlCommercial.set(imgSlides[2], {
              display: "block"
            })
            .to(progressBar, slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[2], slideTime, {
              autoAlpha: 1
            }, 0)
            .to(imgSlides[2], slideTime, {
              autoAlpha: 0
            }, stayTime)
            .to(progressBar, slideTime, {
              autoAlpha: 0
            }, stayTime)
            .set(imgSlides[2], {
              display: "none",
              onComplete: updateCurrentIndex(0)
            });
          return tlCommercial;
        }
      }
    }
  })
#slideshow{
	position: relative;
}
.imgSlide{
	position: absolute;
	width: 100%;
}
.progress{
  position: absolute;
  width: 100%;
  height:3px;
  background: #F1F1F1;
  z-index: 5;
}
.navCircleContainer {
	position: absolute; 
	display: flex;
    justify-content: space-between;
	padding: 5px;
	bottom: 2.5px;
	left: 12.5%;
	width: 75%;
	height: auto;
}
.navCircle {
	opacity: 0.25;
}
div.navCircle {
  position: relative;
  border-radius: 100%;
  background:#F1F1F1;
}
.navCircle.active  {
	opacity:1;
}
@media only screen and (min-width: 768px) {
	div.navCircle{
		width: 30px;
		height: 30px;
	}
}
@media only screen and (max-width: 767px) {
	div.navCircle{
		width: 15px;
		height: 15px;
	}
}
.navCircle span {
	position: absolute;
	color:#F1F1F1;
	font-weight: bold;
	left: 50%;
	-moz-transform: translateX(-50%);
	-webkit-transform: translateX(-50%);
	-ms-transform: translateX(-50%);
	-o-transform: translateX(-50%);
	transform: translateX(-50%);
}
@media only screen and (min-width: 768px) {
	.navCircle span {
		bottom: 30px;
	}
}
@media only screen and (max-width: 767px) {
	.navCircle span {
		bottom: 20px;
	}
}
.navArrow {
	position: absolute;
	top: 50%;
	color:#F1F1F1;
	-moz-transform: translateY(-50%);
	-webkit-transform: translateY(-50%);
	-ms-transform: translateY(-50%);
	-o-transform: translateY(-50%);
	transform: translateY(-50%);
}
#navArrowLeft {
	left: 0%;
}
#navArrowRight {
	right: 0%;
}
img {
	width: 100%;
	height: auto;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.15.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/jquery.gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<div ng-app="appBanner" ng-controller="bannerCtrl"  banner id="slideshow" ng-mouseover="slideshowHover = true" ng-mouseleave="slideshowHover = false" ng-init="slideshowHover = false">
  <!-- green field with lake -->
	<img class="imgSlide" src="http://cdn.morguefile.com/imageData/public/files/i/imma/08/l/14089545069hw66.jpg" >
  
 <!-- waterfall -->
	<img class="imgSlide" src="http://cdn.morguefile.com/imageData/public/files/i/imma/preview/fldr_2012_09_09/file3231347173227.jpg" >
  
  <!-- red sunset -->
	<img class="imgSlide" src="http://cdn.morguefile.com/imageData/public/files/i/imma/preview/fldr_2012_07_22/file541342984669.jpg" >
	<div class="progress"></div>
	<div id="navArrowLeft" class="navArrow bannerNav" ng-click="prevSlide()">
		<div class="hidden-xs">
			<i class="fa fa-angle-double-left fa-5x"></i>
		</div>
		<div class="hidden-sm hidden-md hidden-lg">
			<i class="fa fa-angle-double-left fa-2x"></i>
		</div>
	</div>
	<div id="navArrowRight" class="navArrow bannerNav" ng-click="nextSlide()">
		<div class="hidden-xs">
			<i class="fa fa-angle-double-right fa-5x"></i>
		</div>
		<div class="hidden-sm hidden-md hidden-lg">
			<i class="fa fa-angle-double-right fa-2x"></i>
		</div>
	</div>
	<div class="navCircleContainer">														
		<div  class="navCircle bannerNav" ng-active="isCurrentSlideIndex === 0" ng-mouseover="navCircleAutoHover = true" ng-mouseleave="navCircleAutoHover = false" ng-init="navCircleAutoHover = false"  ng-click="play('auto')"><span class="bannerNav fade" ng-show="navCircleAutoHover === true">Lake</span></div>
		<div  class="navCircle bannerNav" ng-active="isCurrentSlideIndex === 1" ng-mouseover="navCircleBoatownersHover = true" ng-mouseleave="navCircleBoatownersHover = false" ng-init="navCircleBoatownersHover = false"  ng-click="play('boatowners')"><span class="bannerNav  fade" ng-show="navCircleBoatownersHover === true">Waterfall</span></div>
		<div  class="navCircle bannerNav" ng-active="isCurrentSlideIndex === 2" ng-mouseover="navCircleCommercialHover = true" ng-mouseleave="navCircleCommercialHover = false" ng-init="navCircleCommercialHover = false"  ng-click="play('commercial')"><span class="bannerNav fade" ng-show="navCircleCommercialHover === true"> Sunset</span></div>
	</div>
</div>

工作代码笔链接

我在stackoverflow中遇到了一些问题,但提供了工作代码笔链接。我的问题是,updateCurrentIndex(nextIndex)与$timeout一起工作,并在每个子时间线的末尾发生在Complete上,它在播放时似乎无法传达索引的正常增量。

因此,如果您在时间轴有时间转到下一张幻灯片之前单击底部的下一个、上一个或任何直接转到圆形按钮(索引在用户控制之外增加),则此操作效果良好。但是,当时间线播放下一张幻灯片时,控制器中的索引没有意识到这一变化,并且变得不同步。有人指出$timeout服务是解决这个问题的一种方法,但它仍然不起作用。非常感谢您的帮助。

演示中有很多代码需要整理,但有两个无效的函数引用,如:

onComplete: updateCurrentIndex(2)

首先,这些是硬编码的值,其次,它们将立即调用,而不是像您所期望的那样在onComplete激发时调用:

要传递函数作为参考,您不能使用(),所以正确的方法是:

onComplete: updateCurrentIndex

但由于您需要传递参数,因此需要以下内容:

onComplete: function(arg1,arg2){ // not sure what arguments are available
   var newIndex = // I'm not sure how to get index in this event
   updateCurrentIndex(newIndex);
}

我刚刚想明白了。我的问题如下:onComplete:updateCurrentIndex,onCompleteParams:[nextIndex]

我是这样传递的:onComplete:updateCurrentIndex(2)

是的,它正在立即执行。它现在起作用了。

最新更新