1

I would like to know if anybody knows a more efficient way to show / hide columns in a table powered by angularjs:

I have a large table (20+ columns, 1000000+ rows) and implemented a feature to show / hide columns based on user preferences. I do this via ng-if on every table cell. This triggers a large watcher count on initial load of the table and the angular digest cycle is going crazy with more then 4000 watchers on a single page.

My main idea to solve the performance problems was to reduce the watcher count. For this purpose I use this library that does nothing else then disabling watchers that are not in the viewport. So far so good, performance got better, but what if I would add more and more features to the table? It looks like this show / hide columns feature will be my performance bottleneck forever (and according to chromes angularJS digest timing analyses it is).

Conclusion: ng-if doesn't look like a good approach to show / hide columns because of the high watcher count and bad performance. Does anybody know a smarter solution to show / hide columns?

Edit: I already have pagination of 200 rows per page, however the problem still persists and of course I aim for a scalable solution.

chillyistkult
  • 959
  • 2
  • 11
  • 22
  • 1
    I think the craziest thing here is to show 1000000+ rows on an webapp... – Mistalis Jan 16 '17 at 15:01
  • paging would be a good idea, then you could limit the # of watches on the page at a time – Austin Jan 16 '17 at 15:03
  • I already have pagination of 200 rows at a time however the watcher count is still too high and of course it does not scale very well. – chillyistkult Jan 16 '17 at 15:21
  • Don't know how it would perform compared to ng-if in the view, but maybe you could build your columns as a new list in the controller, filter the value in it according to user interactions, and redraw the table? Dunno if this will solve the performance issue (probably not...), but at least you would have only one watcher on your column filter. – Ripley511 Jan 16 '17 at 15:30
  • why not put the `ng-if` per column instead of per cell? – Anthony C Jan 16 '17 at 15:53
  • 1
    @AnthonyC How do you want to hide a whole column if the ng-if is only present in the table header? A table is rendered row by row not column by column. – chillyistkult Jan 16 '17 at 16:05
  • 1
    You can do it by clever combination of CSS and ng-if on client side, however really this should be done in combination, you should be filling out your table using some ajax call (not sure if you are) and have the server only serve out the columns requested that way you can cache several pages above and below (keeping the user experience smoothe) and not carrying around unncessary data. Of course this is caveated by the question of how often the user changes their column preferences – Ahmed Masud Jan 16 '17 at 16:12
  • @chillyistkult, somehow I thought you had implemented your own function to render a table rather than using html table... so pls ignore my comment earlier. Would you consider to use a plugin for rendering the table, something like `http://ui-grid.info/` can be useful to your problem, it supports column virtualization & pagination. – Anthony C Jan 16 '17 at 16:52

1 Answers1

2

You can try with CSS classes applied to the all table cells and respective header cells with different class names.

EG: column-1, column-2 ect

Define the class definitions in the angular string and place in between style tag as expression

EG:

In controllers js

$scope.columnStyleDefs = '.column-1{display:none},.column-1{display:table-cell},...';

You can chnage "columnStyleDefs" as necessary when user change their preferences

In html template

<style>
{{columnStyleDefs}}
</style>

I home this may help you for the above assignment.

w.Bala
  • 129
  • 3