Why The World Needed Another AngularJS Grid
Join the DZone community and get the full member experience.Join For Free
Breaking for Christmas at the end of 2014, I left work frustrated. We released a new system into production with 'usability issues' due to our choice of grid component. Every time we started a new project the question 'which grid should we use' came up and each time there was debate. Each grid had it's merits, no grid fit well. We were on our third project in three years to be using AngularJS, having tested 5 different grids that 'worked' with AngularJS.
In the beginning we were new to AngularJS, so we decided to use ng-grid. We found the basic interface into ng-grid nice and simple, an AngularJS directive that took a list of columns and a list of rows. However we also needed to have checkbox selection and grouping, and found to get these items from ng-grid required using plugins, looking at ng-grid source code and hacking around. These we could live with (ie our users don't care about these things) but found frustrating developers. Once our tables started to grow in size beyond 20 columns and once we introduced pinned columns, the grid gave the user experience that the application had stalled - in other words it made the application unusable.
So for our more complex tables we went with jxqGrid. jqxGrid performed much better with large data-sets, but we still found it lacking. It behaved a bit clunky, was tricky to extend and customise, and wasn't native to AngularJS (making it not 'natural' for the AngularJS developer). We stuck with jqxGrid, taking it as the 'best choice for now'.
We also considered SlickGrid. It's widely adopted, free, and performed very well. However it didn't support pinned columns (unless you went with a branch) and it wasn't written with AngularJS in mind.
I realised in 2014 that ng-grid was been rewritten, that ui-grid was going to be the new ng-grid and solve the performance problems. So I kept a close eye on ui-grid and was excited in late in 2014 when I could download a release candidate of ui-grid. Finally I could say goodbye to jqxGrid and move back into the pure-AngularJS world... I really wanted ui-grid to be my answer...
Performance in ui-grid was disappointing. And it had bugs. OK so the bugs I could deal with, it was a release candidate after all and bugs are expected in initial releases of all software (note: time of writing, 4 months later, it's still release candidate), but the performance made our application fail system test. That means the performance was so bad our test team deemed the application not suitable to be released into production. I was ready to be ui-grids number one fan!! But we took it out and put jqxGrid back in :(
So I began my Christmas break pet project entitled "How do you build a lightning fast grid for AngularJS".
First step was technology choice. I wrote the following prototypes, wanting to consider every possibility:
- Pure AngularJS: Next up was what ui-grid did, use Angular JS for everything - almost using the project to showcase AngularJS. So I created a grid using about eight directives, one for a cell, one for a row, one for a column header e.t.c. and create my own 'ng-repeat' to virtualise the rows (I did not virtualise the columns, I do not believe this should be done as it is not normal to have a table with hundreds of columns). This created a lot of Angular scopes and some extra levels of div's than I wanted (unnecessary baggage). The result was very AngularJS-esque, performed fine (better than ui-grid, but unfair to make a comparison at this point as I didn't have any complex features in) but didn't perform as well as SlickGrid. You see, Angular JS is great for form based applications, where you don't have hundreds of bound values laid out in a grid and scrolling. I still use Angular JS as my primary building tool for web applications. However the 'free stuff' you get costs CPU processing and redraw lags (waiting for the digest cycle), and grids require fast redraw when been scrolled and virtualised, so the extra logic that AngularJS puts in behind the scenes doesn't work in your favour when building something like a complex grid. So my journey continued, how can a grid be an AngularJS component but yet not use AngularJS???
- Hybrid AngularJS: The final prototype offering, use AngularJS to present the grid (so has an AngularJS interface like ui-grid) but doesn't use AngularJS itself to draw the grid. This incidentally became the evolutionary prototype of what is now Angular Grid. When drawing the grid, not using AngularJS means you don't get two-way-binding. However in my experience, the vast majority of grids don't require this, so supporting it is slowing down everything to cater for the few. The performance, to my surprise, was up to SlickGrid. I say 'to my surprise' as I was expecting it to be harder to come up with a fast grid (if I'd had an inkling I wouldn't of bothered with my SVG and canvas experiments, but they were fun, if you consider alone on your laptop writing code that will never be used 'fun'). But what about AngularJS, what if someone did want two-way-binding, or use AngularJS to customise a cell? Easy - we can add that as an option! If you want to user AngularJS you can, just turn it on and have your rows compiled AngularJS style!!!
The Hybrid AngularJS was the clear winner. The SVG and canvas experiments were fun but ended up in my 'home office software graveyard'. With the prototype under my belt, I felt I had the workings of a grid worthy of investing more time in, so I came up with a list of all the things I wanted in a grid. My list was as follows (otherwise known as requirements):
- AngularJS Interface - Influenced by ng-grid. I wanted it to be simple to pop in a list of rows and columns and off you go. The default settings would cater for everything else.
- Themable via CSS - Everything has a CSS class, everything can be styled. I wanted our CSS guys can 'go to town' making our most important grids very professional for 'board level presentations'.
- Pinned columns & Checkbox Selection - These must work smoothly and be supported as part of the core grid out of the box.
- 'Excel like' filtering - Our users were used to Microsoft Excel, where the user can select values from a set. This must work very fast, so the user can easily slice and dice the data with zero wait times.
- Customisable Filters - Should be easy to add in new filters to the grids data-set. Applications I build typically have custom filters at the top of the grid. I wanted a grid that could easily combine these filters into the core grid filtering.
- Aggregations and Grouping - Having worked in Business Intelligence, I appreciate the need to handle large data sets. Not just display the data, but be able to 'manage' the data. This means group and aggregate on the fly. In the future I expect large data in the browser to become more common.
- Zero Dependencies - Not even JQuery, as it's becoming common to not use JQuery in modern web app development.
- Other stuff - And then it had to support resizable columns, sorting, etc etc
So I coded up the new grid in time for getting back to work in 2015. I introduced Angular Grid to the 'troubled' application. What a breath of fresh air! For the first time we had a grid that performed as well as SlickGrid and had a programming interface native to AngularJS. The styling and customising worked a treat. The grid made our application more responsive than any of the grids that we had used. For the first time I felt our grid choice was without compromise.
And that is the story of Angular Grid. I hope my contribution back to the community can help out if someone is suffering the same frustration I used to with the grid choices for AngularJS. I intend continuing with Angular Grid, making it a great choice for AngularJS, or even non-AngularJS web development.
Opinions expressed by DZone contributors are their own.