iam new to AngularJS. I try to move from Backbone.js to Angular and first think i want to do its quite simple: fadeIn and fadeOut.
So my HTML look like these:
<div id="calendar" style="padding-left: 50px" ng-controller="CalendarButtonController">
<!-- prev button -->
<div class="calendar-btn prev" ng-mouseover="fadeIn()" ng-mouseleave="fadeOut()" fade-duration="5000" fade-target="btnPrev">
<img id="btnPrev" src="img/btn-prev_hover.png">
</div>
<!-- next button -->
<div class="calendar-btn next" ng-mouseover="fadeIn()" ng-mouseleave="fadeOut()" fade-duration="5000" fade-target="btnNext">
<img id="btnNext" src="img/btn-next_hover.png">
</div>
</div>
So the idea is: If the mouse is over prev-button div, the image inside the div will be fade in. In the fade-target-Attribute is the specific ID of the element, which will be faded. On mouseover the element (defined in the fade-target-Attribute) will be fade in and on mouseleave the element will be fade out. So i implemented a controller and a directive:
function CalendarButtonController($scope){
$scope.fadeIn = function() {
$scope.$emit('event', 'fadeIn');
}
$scope.fadeOut = function() {
$scope.$emit('event', 'fadeOut');
}
}
angular.module('components', [])
.directive('fadeDuration', function ($rootScope) {
return {
restrict: 'A',
link: function(scope, el, attrs) {
$rootScope.$on('event', function(event, message) {
if(message == "fadeIn"){
fadeIn();
}
if(message == "fadeOut"){
fadeOut();
}
});
function fadeIn(){
$('#'+attrs.fadeTarget).fadeIn(attrs.fadeDuration);
}
function fadeOut(){
$('#'+attrs.fadeTarget).fadeOut(attrs.fadeDuration);
}
}
}
});
The fadein and fadeout of the element works, but the problem is: If i move the mouse over the prev-button-div both images (prev-Button and next-Button) fade in. But it should only fade in the image of prev-Button. How is it possible, to get only the attribute of an element, where the event was fired? In the directive are alway all attributes from all elements matching the directive.
Edit: And is there a easier way to achieve a fadeIn and fadeOut effect?
Instead of trying to control the DOM events through the scope or controller, move that event binding logic to the directive, and then use normal jquery there. You shouldn't need to communicate with the directives using scope events most of the times.
Easier showing than explaining (checkout the fiddle)
<div ng-controller="itemsController">
<div ng-repeat="item in items">
<div class="item" fade="mouseover" fade-duration="5000" fade-target="item-{{item.name}}">
<span id="item-{{item.name}}">{{item.name}}</span>
</div>
</div>
</div>
myApp.controller('itemsController', function($scope) {
$scope.items = [{ name: 'Foo' }, { name: 'Bar'}, { name: 'Baz'}];
});
myApp.directive('fade', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var fadeDuration = attrs.fadeDuration || 100;
var onEvent = attrs.fade || "mouseover";
// See how the directive alone controls the events, not the scope
element.on(onEvent, function() {
var targetElement = $('#' + attrs.fadeTarget);
targetElement.fadeOut(fadeDuration, function(){
targetElement.fadeIn(fadeDuration);
});
});
}
};
});