i have used jQuery slider in my project in which i am loading images using angular. My current view looks like this;
<div id="slides">
<div class="slides_container">
<a href="" data-ng-repeat="image in gallery">
<img data-ng-src="{{image.imageUrl}}" width="919" height="326" alt="" />
</a>
</div>
</div>
the controller;
blogApp.controller("HomeController", ['$scope', '$resource', function ($scope, $resource) {
var basePath = '/api/',
FrontGallery = $resource(basePath + 'gallery?culture=en-US'),
$scope.gallery = FrontGallery.query();
}]);
And the jQuery slider code (to make it a slider. I'm using this plugin http://archive.slidesjs.com/)
$(document).ready(function () {
$('#slides').slides({
preload: true,
preloadImage: '/content/images/theme/loading.gif',
play: 5000,
pause: 2500,
hoverPause: true
});
});
When, i try this code, my all images are loaded from database (debugged it through firebug) but jQuery slider isn't applying the animation or sliding effect to it
And when i remove the data-ng-repeat="image in gallery
and use Some static content i.e images, i get the sliding effect back.
What's the problem here. I think Angular is manipulating some how my DOM. That's why i'm getting this problem whenever i put i.e use some angular attributes on my slider.
Note: i have the same issue with jQuery news i.e jQuery InnerFade
plugin http://medienfreunde.com/lab/innerfade/
Here is how the innerFade
is used;
<h1>
<img src="/content/images/theme/hotnews.png" alt="" />Hot News</h1>
<ul id="news">
<li class="ng-repeat:headline in news">
<span class="ng-bind:headline.description"></span>
<a href="#" title="Read More">» more</a>
</li>
</ul>
and the controller;
var HotNews = $resource(basePath + 'article/hotnews?culture=en-US');
$scope.news = HotNews.query();
How do i fix these problems?
Update 2:
Here is my routes;
// declare a module
var blogApp = angular
.module('blogApp', ['ngResource', 'ngSanitize'])
.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
//$locationProvider.html5Mode(true);
//configure the routes
$routeProvider
.when('/', {
// list the home page
templateUrl: "tmpl/home.html",
controller: "HomeController"
})
.when('/article/:id', {
// access custom param
foo: "hello world",
// list the home page
templateUrl: "tmpl/article.html",
controller: "ArticleController"
})
.when('/404', {
template: '<h1>404 Not Found!</h1>'
})
.otherwise({ redirectTo: '/404' });
}]);
Solution #1:
Temporary, (As @Jason Goemaat answered) works for me. So, here is what i have done. I didn't create any directive
but straightly i injected the $timeout
to my controller and then i did the following;
$timeout(function () {
jQuery('#news').innerfade({
animationtype: 'slide',
speed: 750,
timeout: 2000,
type: 'random',
containerheight: '1em'
});
jQuery('#slides').slides({
preload: true,
preloadImage: 'image/theme/loading.gif',
play: 5000,
pause: 2500,
hoverPause: true
});
}, 100);
And it did work for both i.e for Slider
and for InnerFade
$(document).ready(function () {
is firing before angular has loaded the content onto the page. The jQuery slider script should only be activated after angular has loaded the content. Part of the problem here is that angular does not provide a callback for $digest
so you don't have an event to listen for.
The content load -> event callback -> ui build, while common in jQuery and standard javascript thinking, its not part of the angular mentality. Luckily angular has an insanely powerful method for handling this problem.
What you need is to turn the jQuery slideshow script into an angular directive. Then it will become part of the angular process space and get instantiated as a part of the angular digest cycle.
Something like
<div id="slides" my-slideshow >
<div class="slides_container">
<a href="" data-ng-repeat="image in gallery">
<img data-ng-src="{{image.imageUrl}}" width="919" height="326" alt="" />
</a>
</div>
</div>
Good luck!
Happy example time using innerfade (I have not tested this yet, will do ASAP). First your application must declare an angular module if it doesn't already. ng-app="myModule"
. http://docs.angularjs.org/api/angular.module
(make sure your controller is attached as well!)
Now you can declare a directive on that module. Which is super cool.
angular.module('myModule').directive("innerFade", function () {
var res = {
restrict : 'C',
link : function (scope, element, attrs) {
scope.$watch(attrs.innerFade, function(){
element.innerfade({
speed: 'slow',
timeout: 1000,
type: 'sequence',
containerheight: '1.5em'
});
});
}
};
return res;
});
The way this works is pretty simple. The $watch
function will monitor the part of scope containing your data. When that changes (including initialization), it will fire the innerfade
jQuery function on the element
with the directive. We are also passing 'C' to the restrict argument so this custom directive will be a class only directive (I noticed you seem to like that).
<ul class="inner-fade:innerData" >
<li class="ng-repeat:fadeItem in innerData">{{fadeItem}}</li>
</ul>
Now all you have to do is bind the data to $scope.innerData
in your controller (bind it any way you like including ajax), and it will just work. You can even change the data on $scope.innerData
and it will update with full jQuery glory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With