繁体   English   中英

使用Angular指令中的更改更新Angular Controller

[英]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> 

我有一个控制器,它根据currentIndex接收来自用户的输入:下一个,上一个等。 我有一个运行在指令中的javascript时间轴,该指令会在播放currentIndex时更改它。 在每个嵌套子时间轴的末尾,都会触发updateCurrentIndex。 对于我来说,有必要将此更改传达回控制器,以便下一个先前的更改可以在有意义的currentIndex上工作,而不仅仅是在开始时初始化的内容。 我指令中的监视正在从控制器中注册currentIndex = 0初始化。 因此,我知道部分沟通工作; 这是从指令到控制器的问题。

我的指令的作用域设置为true,restriction为'E',如何将这些currentIndex更改返回给控制器,以便可以根据用户输入适当地对currentIndex进行增减? 我非常了解chrome调试器,但是在指令的范围内找不到currentIndex。 我认为对控制器使用正确的关系范围以及应用将是答案,但是我被困住了。

Angular不知道GreenSock何时进行更改,因此您的范围尚未更新。 您可以使用$scope.$apply()$timeout()类的方法来执行此操作。 使用$ apply可能会出现摘要错误,因此我会在onComplete回调中使用$ timeout。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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