web-dev-qa-db-ja.com

Angular-UIのカルーセルスライドイベントにどのようにバインドしますか?

私はAngular-UIのカルーセルを使用していますが、Googleチャートが表示された後、再描画するように指示する必要があります。私が読んだことにもかかわらず、私はイベントに夢中になっているようには見えません。

私の試みを参照してください: http://plnkr.co/edit/Dt0wdzeimBcDlOONRiJJ?p=preview

HTML:

<carousel id="myC" interval="myInterval">
  <slide ng-repeat="slide in slides" active="slide.active">
    <img ng-src="{{slide.image}}" style="margin:auto;">
    <div class="carousel-caption">
      <h4>Slide {{$index}}</h4>
      <p>{{slide.text}}</p>
    </div>
  </slide>
</carousel>

ドキュメントの読み込み時:

$('#myC').live('slid.bs.carousel', function (event) { console.log("slid"); } );

次のように機能するはずです: http://jsfiddle.net/9fwuq/ --non-angular-uiカルーセル

おそらく、私のチャートがスライドして表示されたという事実にフックするためのより多くのAngular方法がありますか?

13
jduprey

私が考えることができる3つの方法があり、それはあなたの要件に依存します。

例については、 http://plnkr.co/edit/FnI8ZX4UQYS9mDUlrf6o?p=preview を参照してください。

  1. 個々のスライドに$ scope。$ watchを使用して、スライドがアクティブになっているかどうかを確認します。

    $scope.$watch('slides[0].active', function (active) {
      if (active) {
        console.log('slide 0 is active');
      }
    });
    
  2. $ scope。$ watchをカスタム関数とともに使用して、アクティブなスライドを見つけます。

    $scope.$watch(function () {
      for (var i = 0; i < slides.length; i++) {
        if (slides[i].active) {
          return slides[i];
        }
      }
    }, function (currentSlide, previousSlide) {
      if (currentSlide !== previousSlide) {
        console.log('currentSlide:', currentSlide);
      }
    });
    
  3. カスタムディレクティブを使用して、カルーセルディレクティブのselect()関数をインターセプトします。

    .directive('onCarouselChange', function ($parse) {
      return {
        require: 'carousel',
        link: function (scope, element, attrs, carouselCtrl) {
          var fn = $parse(attrs.onCarouselChange);
          var origSelect = carouselCtrl.select;
          carouselCtrl.select = function (nextSlide, direction) {
            if (nextSlide !== this.currentSlide) {
              fn(scope, {
                nextSlide: nextSlide,
                direction: direction,
              });
            }
            return origSelect.apply(this, arguments);
          };
        }
      };
    });
    

    次のように使用します。

    $scope.onSlideChanged = function (nextSlide, direction) {
        console.log('onSlideChanged:', direction, nextSlide);
    };
    

    およびhtmlテンプレート:

    <carousel interval="myInterval" on-carousel-change="onSlideChanged(nextSlide, direction)">
    ...
    

この助けを願っています:)

35
runTarm

AngularUI Bootstrapは、すべてのコントローラーにプレフィックスuibを付けるため、コントローラーの命名規則を変更しました。以下は、runTarm

Angular:

.directive('onCarouselChange', function($parse) {
    return {
        require: '^uibCarousel',
        link: function(scope, element, attrs, carouselCtrl) {
            var fn = $parse(attrs.onCarouselChange);
            var origSelect = carouselCtrl.select;
            carouselCtrl.select = function(nextSlide, direction, nextIndex) {
                if (nextSlide !== this.currentSlide) {
                    fn(scope, {
                        nextSlide: nextSlide,
                        direction: direction,
                        nextIndex: this.indexOfSlide(nextSlide)
                    });
                }
                return origSelect.apply(this, arguments);
            };
        }
    };
});

TypeScriptでAngular:

module App.Directive {

    export class CarouselChange implements ng.IDirective {

        public require: string = '^uibCarousel';

        constructor(private $parse: ng.IParseService) { }

        public link: ng.IDirectiveLinkFn = (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: any, carouselCtrl: any) => {
            var fn = this.$parse(attributes.carouselChange);
            var origSelect = carouselCtrl.select;
            carouselCtrl.select = function(nextSlide, direction) {
                if (nextSlide !== this.currentSlide) {
                    fn(scope, {
                        nextSlide: nextSlide,
                        direction: direction
                    });
                }
                return origSelect.apply(this, arguments);
            };
        }

        static Factory(): ng.IDirectiveFactory {
            var directive: ng.IDirectiveFactory = ($parse: ng.IParseService) => new CarouselChange($parse);
            directive['$inject'] = ["$parse"];
            return directive;
        }
    }
}

ありがとう、

6
Manish Kumar

RunTarmの回答に従って、次のスライドのインデックスを知りたい場合は、次のようなものを追加する必要があります。

 .directive('onCarouselChange', function ($parse) {
    return {
      require: 'carousel',
          link: function (scope, element, attrs, carouselCtrl) {
            var fn = $parse(attrs.onCarouselChange);
            var origSelect = carouselCtrl.select;
            carouselCtrl.select = function (nextSlide, direction,nextIndex) {
      if (nextSlide !== this.currentSlide) {
        fn(scope, {
          nextSlide: nextSlide,
          direction: direction,
          nextIndex:this.indexOfSlide(nextSlide)
        });
      }
      return origSelect.apply(this, arguments);
    };
  }
  };
})

次に、コントローラーで、新しいインデックスをキャッチするためにこれを行う必要があります。

$scope.onSlideChanged = function (nextSlide, direction, nextIndex) {
    console.log(nextIndex);
}
3
Lu Chinke

スライドがビューにスライドし終えると(つまり、スライドアニメーションが終了すると)コールバックを呼び出すように、runTarmの回答を変更することができました。これが私のコードです:

.directive('onCarouselChange', function ($animate, $parse) {
    return {
        require: 'carousel',
        link: function (scope, element, attrs, carouselCtrl) {
            var fn = $parse(attrs.onCarouselChange);
            var origSelect = carouselCtrl.select;
            carouselCtrl.select = function (nextSlide, direction) {
                if (nextSlide !== this.currentSlide) {
                    $animate.on('addClass', nextSlide.$element, function (elem, phase) {
                        if (phase === 'close') {
                            fn(scope, {
                                nextSlide: nextSlide,
                                direction: direction,
                            });
                            $animate.off('addClass', elem);
                        }
                    });
                }
                return origSelect.apply(this, arguments);
            };
        }
    };
});

秘密は、アニメーションが終了したら、$ animateのイベントハンドラーを使用して関数を呼び出すことにあります。

1
R. Kazeno

スライドが表示されたときにビデオの再生を開始し、スライドが表示されたときに一時停止したい場合は、次のようにします。

[〜#〜] js [〜#〜]

{# Uses angular v1.3.20 & angular-ui-bootstrap v0.13.4 Carousel #}
{% addtoblock "js" %}<script type="text/javascript">
angular.module('videoplay', []).directive('videoAutoCtrl', function() {
  return {
    require: '^carousel',
    link: function(scope, element, attrs) {
      var video = element[0];
      function setstate(visible) {
        if(visible) {
          video.play();
        } else {
          video.pause();
        }
      }
      // Because $watch calls $parse on the 1st arg, the property doesn't need to exist on first load
      scope.$parent.$watch('active', setstate);
    }
  };
});
</script>{% endaddtoblock %}
{% addtoblock "ng-requires" %}videoplay{% endaddtoblock %}

注:Django用の追加ビットがあります

HTML:

<carousel interval="15000">
  <slide>
   <video class="img-responsive-upscale" video-auto-ctrl loop preload="metadata">
    <source src=
...
0
racitup

これは、runTarmの#2と#3の間のどこかでコントローラーを使用する別の方法です。

元のHTML +新しいdiv:

<carousel id="myC" interval="myInterval">
  <slide ng-repeat="slide in slides" active="slide.active">
    <div ng-controller="SlideController"> <!-- NEW DIV -->
      <img ng-src="{{slide.image}}" style="margin:auto;">
      <div class="carousel-caption">
        <h4>Slide {{$index}}</h4>
        <p>{{slide.text}}</p>
      </div>
    </div>
  </slide>
</carousel>

カスタムコントローラー:

  .controller('SlideController',
    function($log, $scope) {
      var slide = $scope.slide;
      $scope.$watch('slide.active', function(newValue) {
        if (newValue) {
          $log.info("ACTIVE", slide.id);
        }
      });
    });
0
ionous