In AngularJS, your Controllers don't know anything about your DOM (Document Object Model) - they know about data and about exposing behavior. Views, on the other hand, are all about the DOM; but, they know nothing about user interactions. All user interactions and UI (User Interface) events are managed by Directives. When you get into AngularJS, it can be really tricky to wrap your head around this division of responsibilities. This is especially true when you're dealing with a situation that feels particularly "UI oriented." Cross-fading images, for example, might be something you've done a thousand times with jQuery; but, in an AngularJS context, old-habits can be hard to translate.
When I refer to "cross-fading" images, I mean fading one image into another image during something like a slide-show or an image presentation. AngularJS makes it dead-simple to show an image based on a user's choice; in fact, that's the kind of stuff that makes AngularJS seem completely magical. But the "cross-fade" effect, on the other hand, is not something that AngularJS really facilitates.
So, how can we cross-fade images in an "Angular" way? Well, to start with, I would suggest not cross-fading the images at all. As I've talked about before, by delaying the programming of "effects," you help to ensure that the appropriate division of responsibilities is maintained within your AngularJS application. Then, only after the low-fidelity version works, should you go in and add the effects using a Directive (or set of Directives).
In the following demo, I am using the custom Directive, "bnFadeHelper." However, I added this Directive only after I had my image presentation demo working. This kept all of the data in my Controller and properly quarantined the animations (and animation logic) within my Directive. In fact, you can take the directive out and the demo still works.
Notice how simple my Controller is? It's basically a collection of objects and a single public method that allows for the selection of one of those objects. There's nothing in my Controller that's related to the image cross-fade. All of that information - all of that DOM (Document Object Model) awareness - is siloed within the bnFadeHelper directive.
The bnFadeHelper Directive watches for changes in the data model; and, when it sees the image selection change, it shows a copy of the previous image and then fades it out of view once it has detected that the new image selection has finished loading.
Want to use code from this post? Check out the license.
Great post! thanks
My pleasure :D
One important tip - jquery must be included before angularjs. Otherwise, only jqlite is available and doesn't support the needed .find features. It took me a while to figure that out, but once I got it right the code worked just fine.
Thanks I was just planning to do something like this when I found your tutorial. I was planning to use some jquery fade effects inside the Directive but I prefer your approach using mostly CSS rules.