I needed to allow for a particular part of a page I was working on to scroll independently of the page. Typically you would just use overflow-y: auto and be call it a day. However the default renderings of these scroll bars stick out like sore thumbs in the middle of a page.
So I quickly googled to see if there were any awesome angular.js directives that allowed you to style scrollbars. Much like the flyout, confirm dialog, and dropdown, I didn't find much online. I did find a bunch of posts on jQuery controls that have nice scrolling like jScrollPane. I figured that instead of creating one from scratch this time, I was more curious on the proper way of integrating jQuery plugins with angular.js.
I found this video that shows an integration with the chosen jQuery plugin, which incidentally was something I was looking at when I decided to create my own drop down, and I decided to watch it. The video is pretty good, but regardless if you watch it or not I'll show you how to integrate a jQuery plugin with angular.js.
So after viewing that example I figured it would be pretty easy. It should be just adding the JS files and creating a directive that applies the plugin to the element in the link function. It pretty much boils down to the following directive.
Just replace the 'NAME' with a proper name for the directive, and 'PLUGINFUNCTION' with the actual function to execute the plugin. I have it restricted as "A" so you can just add the attribute to whatever element you want it to be on. So to use the jScrollPane plugin you can just use this.
I tried it out in a fiddle real quick and it worked fine. However when I tried to use it in my application it wasn't working. After thinking about it for a bit, and reading some additional documentation for the jScrollPane, I realized the issue was, like most JS heavy applications, were being driven by data from services, or in my case being asynchronously loaded via websockets.
So now I found the function to reinitialize the plugin, but I needed to figure out how to inform the directive to do it. I ended up deciding to use a built in angular functionality to do so. The scope.$broadcast and scope.$on seemed to be exactly what I was looking for. Whenever what was driving the content changed it would send a message down scope using $broadcast, and $on would listen for the message. That made me feel good about the separation of concerns. Essentially the scrollPane directive could just listen for an event from somewhere up the parent scope and whatever was driving the data or re-sizing of the page could drive the sending of the message. I ended up just using a generic "refresh" message name for it. Here is the end result for the directive:
Here is the end result:
So I quickly googled to see if there were any awesome angular.js directives that allowed you to style scrollbars. Much like the flyout, confirm dialog, and dropdown, I didn't find much online. I did find a bunch of posts on jQuery controls that have nice scrolling like jScrollPane. I figured that instead of creating one from scratch this time, I was more curious on the proper way of integrating jQuery plugins with angular.js.
I found this video that shows an integration with the chosen jQuery plugin, which incidentally was something I was looking at when I decided to create my own drop down, and I decided to watch it. The video is pretty good, but regardless if you watch it or not I'll show you how to integrate a jQuery plugin with angular.js.
So after viewing that example I figured it would be pretty easy. It should be just adding the JS files and creating a directive that applies the plugin to the element in the link function. It pretty much boils down to the following directive.
.directive('NAME', function(){ function link(scope, element){ // you can use the angular.element instead $(element).PLUGINFUNCTION(); } return { link:link, restrict : "A" }; });
Just replace the 'NAME' with a proper name for the directive, and 'PLUGINFUNCTION' with the actual function to execute the plugin. I have it restricted as "A" so you can just add the attribute to whatever element you want it to be on. So to use the jScrollPane plugin you can just use this.
.directive('scrollPane', function(){ function link(scope, element){ // you can use the angular.element instead $(element).jScrollPane(); } return { link:link, restrict : "A" }; });
I tried it out in a fiddle real quick and it worked fine. However when I tried to use it in my application it wasn't working. After thinking about it for a bit, and reading some additional documentation for the jScrollPane, I realized the issue was, like most JS heavy applications, were being driven by data from services, or in my case being asynchronously loaded via websockets.
So now I found the function to reinitialize the plugin, but I needed to figure out how to inform the directive to do it. I ended up deciding to use a built in angular functionality to do so. The scope.$broadcast and scope.$on seemed to be exactly what I was looking for. Whenever what was driving the content changed it would send a message down scope using $broadcast, and $on would listen for the message. That made me feel good about the separation of concerns. Essentially the scrollPane directive could just listen for an event from somewhere up the parent scope and whatever was driving the data or re-sizing of the page could drive the sending of the message. I ended up just using a generic "refresh" message name for it. Here is the end result for the directive:
.directive('scrollPane', function(){ function link(scope, element, attr){ var $element = $(element), api; // element.jScrollPane(); //In real world Angular would replace jQuery $element.jScrollPane(); api = $element.data('jsp'); scope.$on('refresh', function onRefresh(event, args){ api.reinitialise(); }); } return { restrict: 'A', link: link }; });
Here is the end result:
No comments:
Post a Comment