daniel-nagy / fixed-table-header

Fixed table header directive.
MIT License
88 stars 36 forks source link

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! #3

Open PsyGik opened 8 years ago

PsyGik commented 8 years ago

Using code from demo. Only change is the dataset. Mine has 50 items.

wmichaelfeltman commented 8 years ago

Have the same issue with Angular 1.5 and Angular Material 1.0.5 and the latest md-data-table.

Error: $rootScope:infdig
Infinite $digest Loop
10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [[{"msg":"fn: function (){return g.width}","newVal":"135px","oldVal":"137px"},{"msg":"fn: function (){return g.width}","newVal":"406px","oldVal":"412px"},{"msg":"fn: function (){return g.width}","newVal":"174px","oldVal":"177px"},{"msg":"fn: function (){return g.width}","newVal":"103px","oldVal":"105px"},{"msg":"fn: function (){return g.width}","newVal":"109px","oldVal":"111px"},{"msg":"fn: function (){return g.width}","newVal":"143px","oldVal":"145px"},{"msg":"fn: function (){return g.width}","newVal":"174px","oldVal":"177px"},{"msg":"fn: function (){return g.width}","newVal":"112px","oldVal":"114px"},{"msg":"fn: function (){return g.width}","newVal":"176px","oldVal":"180px"},{"msg":"fn: function (){return g.width}","newVal":"171px","oldVal":"173px"}],[{"msg":"fn: function (){return g.width}","newVal":"132px","oldVal":"135px"},{"msg":"fn: function (){return g.width}","newVal":"400px","oldVal":"406px"},{"msg":"fn: function (){return g.width}","newVal":"171px","oldVal":"174px"},{"msg":"fn: function (){return g.width}","newVal":"101px","oldVal":"103px"},{"msg":"fn: function (){return g.width}","newVal":"107px","oldVal":"109px"},{"msg":"fn: function (){return g.width}","newVal":"140px","oldVal":"143px"},{"msg":"fn: function (){return g.width}","newVal":"171px","oldVal":"174px"},{"msg":"fn: function (){return g.width}","newVal":"109px","oldVal":"112px"},{"msg":"fn: function (){return g.width}","newVal":"174px","oldVal":"176px"},{"msg":"fn: function (){return g.width}","newVal":"168px","oldVal":"171px"}],[{"msg":"fn: function (){return g.width}","newVal":"130px","oldVal":"132px"},{"msg":"fn: function (){return g.width}","newVal":"394px","oldVal":"400px"},{"msg":"fn: function (){return g.width}","newVal":"168px","oldVal":"171px"},{"msg":"fn: function (){return g.width}","newVal":"99px","oldVal":"101px"},{"msg":"fn: function (){return g.width}","newVal":"104px","oldVal":"107px"},{"msg":"fn: function (){return g.width}","newVal":"138px","oldVal":"140px"},{"msg":"fn: function (){return g.width}","newVal":"168px","oldVal":"171px"},{"msg":"fn: function (){return g.width}","newVal":"107px","oldVal":"109px"},{"msg":"fn: function (){return g.width}","newVal":"170px","oldVal":"174px"},{"msg":"fn: function (){return g.width}","newVal":"165px","oldVal":"168px"}],[{"msg":"fn: function (){return g.width}","newVal":"127px","oldVal":"130px"},{"msg":"fn: function (){return g.width}","newVal":"387px","oldVal":"394px"},{"msg":"fn: function (){return g.width}","newVal":"165px","oldVal":"168px"},{"msg":"fn: function (){return g.width}","newVal":"96px","oldVal":"99px"},{"msg":"fn: function (){return g.width}","newVal":"102px","oldVal":"104px"},{"msg":"fn: function (){return g.width}","newVal":"135px","oldVal":"138px"},{"msg":"fn: function (){return g.width}","newVal":"164px","oldVal":"168px"},{"msg":"fn: function (){return g.width}","newVal":"105px","oldVal":"107px"},{"msg":"fn: function (){return g.width}","newVal":"167px","oldVal":"170px"},{"msg":"fn: function (){return g.width}","newVal":"163px","oldVal":"165px"}],[{"msg":"fn: function (){return g.width}","newVal":"125px","oldVal":"127px"},{"msg":"fn: function (){return g.width}","newVal":"381px","oldVal":"387px"},{"msg":"fn: function (){return g.width}","newVal":"162px","oldVal":"165px"},{"msg":"fn: function (){return g.width}","newVal":"94px","oldVal":"96px"},{"msg":"fn: function (){return g.width}","newVal":"100px","oldVal":"102px"},{"msg":"fn: function (){return g.width}","newVal":"132px","oldVal":"135px"},{"msg":"fn: function (){return g.width}","newVal":"161px","oldVal":"164px"},{"msg":"fn: function (){return g.width}","newVal":"102px","oldVal":"105px"},{"msg":"fn: function (){return g.width}","newVal":"164px","oldVal":"167px"},{"msg":"fn: function (){return g.width}","newVal":"160px","oldVal":"163px"}]]

Eventually the app recovers and everything works as expected, but obviously that's not ideal.

wmichaelfeltman commented 8 years ago

Commenting out scope.$watch(cells, updateCells); Almost solves the problem. It suppresses the errors, the header is still fixed and it eliminates some annoying jumping around of column sizes. This introduces 2 new issues: 1. The column headers are not over the columns and 2. There's some blank space between the column headers and the first row.

Obviously the solution is to call updateCells at a later juncture or perhaps to debounce it. I'm looking into these options.

Update: replacing scope.$watch(cells, updateCells); with simply updateCells(); works in my application.

mcblum commented 7 years ago

That didn't work for me for some reason, so I went this route. It's not pretty:

function updateCells() {
                if(processing) {
                    return false;
                }

                processing = true;

                $timeout(() => {
                    let cells = {
                        clone: getCells(header.clone),
                        original: getCells(header.original)
                    };

                    cells.clone.forEach(function (clone, index) {
                        if (clone.data('isClone')) {
                            return;
                        }

                        // prevent duplicating watch listeners
                        clone.data('isClone', true);

                        let cell = cells.original[index];
                        let style = $window.getComputedStyle(cell[0]);

                        let getWidth = function () {
                            return style.width;
                        };

                        let setWidth = function () {
                            marginTop(height());
                            clone.css({minWidth: style.width, maxWidth: style.width});
                        };

                        let listener = scope.$watch(getWidth, setWidth);

                        $window.addEventListener('resize', setWidth);

                        clone.on('$destroy', function () {
                            listener();
                            $window.removeEventListener('resize', setWidth);
                        });

                        cell.on('$destroy', function () {
                            clone.remove();
                        });
                    });

                    processing = false;
                }, 500);
            }