Creating a scope-independent fadein/fadeout directive in AngularJS -


to set stage - not happening within single scope, can bind simple attribute. element want fade in/out not sit inside controller, sits inside ng-app (rootscope). further, button that's clicked in child scope 3 children deep root.

here how i'm solving this:

html (sitting in root scope):

<ul class="nav-secondary actions"    darthfader fadeduration="200"    fadeevent="darthfader:secondarynav"> 

where darthfader directive.

directive:

directive('darthfader',

function() {         return {             restrict: 'a',             link: function($scope, element, attrs) {                 $scope.$on(attrs.fadeevent, function(event,options) {                     $(element)["fade" + options.fade || "in"](attrs.fadeduration || 200);                 });             }         }  }) 

so here i'm creating event handler, specific given element, calling fadein or fadeout, depending on option being passed through event bus (or defaulting fadein/200ms).

i broadcasting event $rootscope trigger event:

$rootscope.$broadcast('darthfader:secondarynav', { fade: "out"}); 

while works, i'm not crazy creating event listener every instance of directive (while don't anticipate having many darthfader's on screen, it's more pattern establish). i'm not crazy coupling attribute in view event handler in both controller & directive, don't have controller wrapping secondary-nav, i'd have bind secondarynav $rootscope, don't love either. questions:

  1. is there way without creating event handler every time instantiate directive? (maybe service store stateful list of elements?)
  2. how should decouple view, controller & directive?
  3. any other obvious questions i'm missing?

cheers!

you mention in question

the element want fade in/out not sit inside controller, sits inside ng-app (rootscope).

i believe if write same functionality, put element in own controller--controllers responsible managing intersection of view , model, you're trying do.

myapp.controller('navcontroller', function($scope) {   $scope.fadedin = false; }); 
<ul ng-controller="navcontroller"   class="nav-secondary actions"    darthfader fadeduration="200"    fadeshown="fadedin"> 
myapp.directive('darthfader', function() {   return {     restrict: 'a',     link: function($scope, element, attrs) {       var duration = attrs.fadeduration || 200;       $scope.$watch(attrs.fadeshown, function(value) {         if (value)           $(element).fadein(duration);         else           $(element).fadeout(duration);       });      }    }; }); 

if you're worried sharing fade in/out state between multiple controllers, should create service share state. (you use $rootscope , event handlers, find shared services easier debug , test.)

myapp.value('navigationstate', {   shown: false });  myapp.controller('navcontroller', function($scope, navigationstate) {   $scope.nav = navigationstate; });  myapp.controller('othercontroller', function($scope, navigationstate) {   $scope.shownav = function() {     navigationstate.shown = true;   };    $scope.hidenav = function() {     navigationstate.shown = false;   }; }); 
<ul ng-controller="navcontroller"   class="nav-secondary actions"    darthfader fadeduration="200"    fadeshown="nav.shown">  <!-- ..... -->  <div ng-controller="othercontroller">   <button ng-click="shownav()">show nav</button>   <button ng-click="hidenav()">hide nav</button> </div> 

Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -