【问题标题】:Updating Angular Controller with changes in Angular directive使用 Angular 指令的更改更新 Angular 控制器
【发布时间】:2016-07-12 13:26:06
【问题描述】:

"use strict";
angular.module("appBanner", [])
    .controller('bannerCtrl', function ($scope) {
		
		//...

        $scope.currentIndex = 0;
        $scope.setCurrentSlideIndex = function (index) {
            $scope.currentIndex = index;
        }

        $scope.isCurrentSlideIndex = function (index) {
            return $scope.currentIndex === index;
        };

        $scope.prevSlide = function () {
            $scope.currentIndex = ($scope.currentIndex < $scope.slides.length - 1) ? ++$scope.currentIndex : 0;
        };

        $scope.nextSlide = function () {
            $scope.currentIndex = ($scope.currentIndex > 0) ? --$scope.currentIndex : $scope.slides.length - 1;
        };
		
		//...

    })
    .directive('banner', function () {
		return {
			templateUrl: 'views/partials/banner.html',
			restrict: 'E',
			transclude: false,
			replace:true,
			scope: false,
			link: function postLink(scope, element, attrs) {
				
				//var imgSlides = ...
				//var progressBar = ...
				//var slideTime = ...
				
				var tlMaster = initMasterTimeline(imgSlides, progressBar, slideTime);
				
				function updateCurrentIndex(index) {
					scope.$apply(function() {
					  //***************************************************
					  /*    How do I communicate the new current index back to my controller from this directive?
					  /*
					  /*****************************************************/
				   });
				}
				
				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]
					});
								
					
					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]
					});
								
					
							
					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]
					});
								
					
					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;
				}
				
				function setProgress (timeline, progressBar){
					TweenMax.set(progressBar, {scaleX:timeline.progress()});
				}
			}
		}
	});
<div ng-app="appBanner" ng-controller="bannerCtrl">
	<img class="imgSlide" src="images/slideshow/slideshow-1.jpg" >
	<img class="imgSlide" src="images/slideshow/slideshow-2.jpg" >
	<img class="imgSlide" src="images/slideshow/slideshow-3.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>

我有一个控制器,它接收来自用户的输入:基于 currentIndex 的下一个、上一个等。我有一个在播放时更改 currentIndex 的指令中运行的 javascript 时间线。在每个嵌套的子时间线结束时,会触发 updateCurrentIndex。我有必要将此更改传达回控制器,以便下一个,前一个在有意义的 currentIndex 上工作,而不仅仅是它在开始时初始化的内容。我的指令中的手表正在从我的控制器注册 currentIndex = 0 初始化。所以,我知道通信的一部分是有效的;从指令到控制器,这就是问题所在。

我的指令将其范围设置为 true 并且限制为 'E' ,我如何将这些 currentIndex 更改返回到控制器,以便 currentIndex 可以根据用户输入适当地递增和递减?我非常了解 chrome 调试器,但在我的指令范围内找不到 currentIndex 。正在考虑将正确的关系范围与控制器一起应用将是答案,但我被卡住了。

【问题讨论】:

  • 另外,如果您不熟悉 Greensock,请不要过分关注它。 onComplete 是一种在时间线末尾运行的实用方法。在这种情况下,它会将 currentIndex 更新到下一张幻灯片。然后该值需要与控制器同步。

标签: angularjs angularjs-directive gsap


【解决方案1】:

Angular 不知道 GreenSock 何时进行更改,因此您的范围尚未更新。您可以使用$scope.$apply()$timeout() 之类的东西来做到这一点。使用 $apply 可能会出现摘要错误,所以我会在 onComplete 回调中使用 $timeout。

function onComplete() {
  $timeout(function() {
    updateCurrentIndex(1);
  });
}

这是一个演示,展示了当您不将 $apply 或 $timeout 与第三方库一起使用时会发生什么……什么都没有!是的,这也包括 jQuery。

http://plnkr.co/edit/Z28hiklSk8IsyQ2Bi45s?p=preview

【讨论】:

猜你喜欢
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2020-03-03
相关资源
最近更新 更多