簡體   English   中英

$超時服務未從指令更新角度控制器

[英]$timeout service not updating angular controller from directive

 "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中工作時遇到了一些麻煩,但是提供了有效的codepen鏈接。 我的問題是,與$ timeout結合使用並在每個子時間軸末尾的onComplete發生的updateCurrentIndex(nextIndex)在播放時似乎無法傳達索引的正常增量。

因此,如果您在時間軸有時間轉到下一張幻燈片之前(在用戶控件外部索引已遞增),請單擊底部的下一個,上一個或任何直接轉到圓圈按鈕,則此方法很好用。 但是,當時間軸播放下一張幻燈片時,控制器中的索引不知道此更改,並且變得不同步。 我已經指出$ 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)

是的,它立即執行。 現在有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM