2

If you are working with Angular, probably you will have case where you want to call some JQUERY library to do something for you. The usual way would be to call JQUERY function on page ready:

$(function(){
   $(element).someJqueryFunction();
});

If your element content is dynamically added using Angular, than this approach is not good as I understood, and you need to create an custom directive in order to fulfill this functionality.

In my case, I want to load bxSlider on <ul class="bxslider"> element, but content of the <ul> element should be loaded using angular ng-repeat directive.

Picture names are collected using REST service from the database.

I call my directive called startslider using the following code:

<div startslider></div> 

My custom Angular directive is: (pictures is variable in the $scope passed from my controller, which called REST service)

application.directive('startslider', function () {
    return {
        restrict: 'A',
        replace: false,
        template: '<ul class="bxslider">' +
                   '<li ng-repeat="picture in pictures">' +
                     '<img ng-src="{{siteURL}}/slide/{{picture.gallery_source}}" alt="" />'
                   '</li>' +
                  '</ul>',


        link: function (scope, elm, attrs) {//from angular documentation, the link: function should be called in order to change/update the dom elements
            elm.ready(function () {
                elm.bxSlider({
                    mode: 'fade',
                    autoControls: true,
                    slideWidth: 360,
                    slideHeight:600
                });




            });
        }
    };
});

As result, I get all the pictures from the database displayed on my screen, but without bxSlider loaded (all pictures displayed one bellow other).

Please note that bxSlider is working, because when I call $(element).bxSlider(); on manually written code, the slider loads.

Why is this happening?

MrD
  • 2,423
  • 3
  • 33
  • 57

3 Answers3

1

EDIT: I think your problem is caused by trying to call the slider on HTMLUListElement, which is an object.

To call the slider on the DOM element, you could use $("." + $(elm[0]).attr('class')) that will use the existing bxslider class, or better assign an id to your <div startslider id="slideshow"></div> and call like $("." + $(elm[0]).attr('id'))

      elm.ready(function() {    
           $("." + $(elm[0]).attr('class')).bxSlider({
                mode: 'fade',
                autoControls: true,
                slideWidth: 360,
                slideHeight:600
           });
      });

Full code: http://jsfiddle.net/z27fJ/

Mihai Alex
  • 678
  • 6
  • 13
  • 1
    When I paste scope.$apply(function() { scope.pictures= scope.startslider; }); I get the following error: Error: [$rootScope:inprog] http://errors.angularjs.org/1.3.0-beta.3/$rootScope/inprog?p0=%24digest – MrD Mar 30 '14 at 13:49
  • 2
    All pictures loaded but one bellow other, just like there is no BxSlider. Really don't know what is happening. – MrD Apr 01 '14 at 20:16
  • Did you checked the jsfiddle? There is a working example there. – Mihai Alex Apr 02 '14 at 09:45
  • I am also unable to render proper slider. Images get stacked top to bottom. Fiddle is working perfectly but unable to integrate the same in my code. – Kunal Kakkad Jul 26 '17 at 20:54
0

Not my solution, but I'd thought I would pass it along.

I like this solution the best (Utilizes directive controllers)

// slightly modified from jsfiddle

// bxSlider directive
controller: function() {},
link: function (scope, element, attrs, controller) {
    controller.initialize = function() {
        element.bxSlider(BX_SLIDER_OPTIONS);
    };
}

// bxSliderItem directive
require: '^bxSlider',
link: function(scope, element, attrs, controller) {
    if (scope.$last) {
        controller.initialize();
    }
}

http://jsfiddle.net/CaioToOn/Q5AcH/8/

Alternate, similar solution, using events (I do not like)

Jquery bxslider not working + Angular js ng-repeat issue

Root issue

  • You cannot call scope.$apply in the middle of a digest cycle.
  • You cannot fire bxSlider() until the template gets compiled.
  • Ultimately, you need to wait for the template to be compiled and available before calling bxSlider()

Calling a function when ng-repeat has finished

Community
  • 1
  • 1
chemoish
  • 1,210
  • 2
  • 13
  • 23
0

this is the directive

.directive('slideit', function () {
return function (scope, elm, attrs) {
    var t = scope.$sliderData;

    scope.$watch(attrs.slideit, function (t) {
        var html = '';
        for (var i = 0; i <= t.length-1; i++) {
            html += '<li><ul class="BXslider"><li class="BXsliderHead"><img src="'+scope.$imageUrl+'flight/'+t[i].code+'.gif" />'+t[i].name+'</li><li class="BXsliderChild">'+t[i].noneStop+'</li><li class="BXsliderChild">'+t[i].oneStop+'</li><li class="BXsliderChild">'+t[i].twoStop+'</li></ul></li>';
        }
        angular.element(document).ready(function () {
            $("#" + $(elm[0]).attr('id')).html(html).bxSlider({

                pager:false,
                minSlides: 3,
                maxSlides: 7,
                slideWidth: 110,
                infiniteLoop: false,
                hideControlOnEnd: true,
                auto: false,
            });
        });
    });
};
});

this is the html in view

  <div ui-if="$sliderData">
        <ul id="experimental" slideit="$sliderData"></ul>
    </div>

and the important part is the dependency of js file

  <script src="/yii-application/frontend/web/js/libraries/angular/angular.min.js"></script>
  <script src="/yii-application/frontend/web/js/libraries/angular/angular-ui.js"></script>
 <script src="/yii-application/frontend/web/js/libraries/jquery/jquery-1.11.3.min.js"></script>
 <script src="/yii-application/frontend/web/js/libraries/flex/jquery.bxslider.min.js"></script>
 <script src="/yii-application/frontend/web/assets/e3dc96ac/js/bootstrap.min.js"></script>
 <script src="/yii-application/frontend/web/js/libraries/jquery-ui/jquery-ui.min.js"></script>
 <script src="/yii-application/frontend/web/js/searchResult.js"></script>
 <script src="/yii-application/frontend/web/js/Flight.js"></script>

and don't forget to put ui in module var app = angular.module('myApp', ['ui']);

this is the bxslider that i use !!!! maybe solve your problem

Mohsen
  • 1,295
  • 1
  • 15
  • 45