3

I'm building a slider, and I'm using the ng-repeat directive to iterate a (RESTful) service to create the slides in the slider.

I've wrapped the slider in a custom directive to initialize it when it's done (ie. in the link function).

var swiper = angular.module('ng-swiper', ['qbusService'])
 .directive('swiper', function(){

 return {
   link : function(scope, element, attrs) {
     $(element).swiper({});
   }
 };

});

However the slider is not initialized correctly, am I missing something?

HTML:

<div class="swiper-container" swiper>
  <div class="swiper-wrapper">

    <!-- for each group -->
    <div class="swiper-slide" ng-repeat="group in groups">

      <ul class="small-block-grid-2">
        <li ng-model="output"
            ng-repeat="output in group.Outputs"
            ng-switch on="output.TypeName"
            class="tile {{output.TypeName}}">
          <a href="" data-reveal-id="outputModal{{output.ID}}">
            <i class="foundicon-idea block" ng-switch-when="dimmer1t"></i>
            <i class="foundicon-idea block" ng-switch-when="dimmer2t"></i>
            <i class="foundicon-clock block" ng-switch-when="timer1"></i>
            <i class="foundicon-smiley block" ng-switch-default></i>
            <h2>{{output.CustomName}}</h2>
          </a>
          <!-- Output Modal Box -->
          <div id="outputModal{{output.ID}}"
               class="reveal-modal xlarge"
               ng-switch on="output.TypeName">

            <h2>{{output.CustomName}}</h2>

            <i class="foundicon-idea block" ng-switch-when="dimmer1t"></i>
            <i class="foundicon-idea block" ng-switch-when="dimmer2t"></i>
            <i class="foundicon-clock block" ng-switch-when="timer1"></i>
            <i class="foundicon-smiley block" ng-switch-default></i>

            <div class="switch large">
              <input id="x" ng-click="turnOff(output)" name="switch-x" type="radio" checked>
              <label for="x">Off</label>

              <input id="x1" ng-click="turnOn(output)" name="switch-x" type="radio">
              <label for="x1">On</label>

              <span></span>
            </div>

            <a class="close-reveal-modal">&#215;</a>
          </div>
        </li>
      </ul>

    </div>

  </div>
</div>
4
  • What is hapenning? How's your html? Commented Mar 26, 2013 at 11:57
  • @CaioToOn I've added the HTML Commented Mar 26, 2013 at 12:10
  • You don't need to wrap you element in jQuery ($(element)...). If you remove it, are you facing an error? Commented Mar 26, 2013 at 12:19
  • @CaioToOn It doesn't throw an error, but it doesn't solve the problem either :) Commented Mar 26, 2013 at 12:25

3 Answers 3

4

You can make your swiper initiate (or update) on an event:

var swiper = angular.module('ng-swiper', ['qbusService'])
 .directive('swiper', function(){

 return {
   link : function(scope, element, attrs) {
     element.swiper({});
     scope.$on("swiper-update", function(){
       element.swiper({});
     })
   }
 };

});

And have either each slide trigger it (effectively updating the slider for each new slide) or only trigger it when the ng-repeat is finished (using the $last property in the ng-repeat's $scope).

Alternatively, you don't need to create a directive for this, just use ng-init to run an update function, for instance:

<div class="swiper-slide" ng-repeat="group in groups" ng-init="updateSwiper($last)">

and have a corresponding function on the parent scope:

var swiper = angular.module('ng-swiper', ['qbusService'])
 .directive('swiper', function(){

 return {
   link : function(scope, element, attrs) {
     scope.updateSwiper = function(bool){
       if (bool) element.swiper({});
     }
   }
 };

});
Sign up to request clarification or add additional context in comments.

2 Comments

Awesome, this is exactly what I was looking for! It keeps my directive nicely seperated from my controller logic and avoids using dirty work-arounds.
There is also the added perk of it updating with your content - you can add/delete a slide and know that the slider will update accordingly :)
1

try to wrapping it around with on ready event of jQuery

var swiper = angular.module('ng-swiper', ['qbusService'])
 .directive('swiper', function(){

 return {
   link : function(scope, element, attrs) {
     $(function() {
        $(element).swiper({});
     });
   }
 };

});

Comments

0

Try wrapping in $timeout to give browser a chance to finish painting the DOM once angular compile process is done:

var swiper = angular.module('ng-swiper', ['qbusService'])
 .directive('swiper', function($timeout){

 return {
   link : function(scope, element, attrs) {
        $timeout(function(){
          $(element).swiper({});
        },10)
   }
 };

});

4 Comments

It says $timeout is not defined, weird.
did you inject it as argument in directive? Will be undefined otherwise
Increasing the timeout to around 200ms did the trick, but I really don't like like this sort of (dirty) approach. Will mark your answer as correct if no no better alternative comes up.
if takes that long chances are is delay due to data from server? Other ways to delay compiler using resolve in config also.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.