简体   繁体   中英

Updating Angular Controller with changes in Angular directive

 "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> 

I have a controller which receives input from the user: next, previous, etc. based on the currentIndex. I have a javascript timeline that runs in the directive that changes the currentIndex as it plays. At the end of each of the nested child timelines, updateCurrentIndex is fired. It is necessary for me to communicate this change back to the controller so that the next, previous works on a meaningful currentIndex, not just what it was initialized in the beginning. The watch within my directive is registering the currentIndex = 0 initialization from my controller. So, I know that part of thecommunication works; its from directive to controller that is the problem.

My directive has its scope set to true and restrict is 'E' , how do I get these currentIndex changes back to controller so currentIndex can be incremented and decremented appropriately based on the user input? I know my way around the chrome debugger fairly well but can't find currentIndex in the scope within my directive . Was thinking that using the correct relational scope to the controller along with apply would be the answer, but I am stuck.

Angular does not know when changes are made by GreenSock, so your scope hasn't been updated. You can do this by using something like $scope.$apply() or $timeout() . You might get digest errors using $apply, so I'd go with using $timeout in your onComplete callback.

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

Here's a demo that shows what happen when you don't use $apply or $timeout with a third-party library... nothing! And yes, that includes jQuery too.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM