Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this width watching AngularJS directive not work upon switching Bootstrap tabs?

I have two Bootstrap tabs on a page and each tab displays a list. I want each list item to be a square and wrote this AngularJS directive to set the height of each list item to be equal to its Bootstrap controlled dynamic width:

app.directive('squareDiv', function () {
    return {
        restrict: "A",
        link: function (scope, element,attr) {
            scope.getWidth = function () {
                return element.width();
            };
            scope.$watch(scope.getWidth, function (width) {
                element.css({ 
                    height: width + 'px'
                });
            }, true);
        }
    };
});

When I load this page, the first tab's list items show up as squares which means the directive is working. But when I click on another tab, the list items there have the default height of 100 px. When I switch back to the first tab, even the list items there have the default height now.

What is going wrong here?

UPDATE 1:

Here is the link to a plunker that illustrates this problem: http://plnkr.co/edit/Pc7keuRXR9R3U6AhZmFE?p=preview

UPDATE 2:

Plunker with Bootstrap replaced by UI-Bootstrap that still has the same problem: http://plnkr.co/edit/rLE1wUAHKzJP6FVnGF6b?p=preview

UPDATE 3:

Plunker with watch for tab switch instead of width change (workaround for the original problem of width watch not working correctly; will need to use a separate directive for adapting to width changes due to window resizing): http://plnkr.co/edit/Y4Goe0cexq979JsIcBxl?p=preview

I would still like to understand why the width watch stops working correctly after a tab switch.

like image 988
Price Avatar asked Oct 29 '15 12:10

Price


1 Answers

Your directive's watcher is one digest cycle behind of what's happening. If you look closely enough, you will see that the very first tab clicking does not do much (nothing logged to console). What you see is your active tab's elements being resized to the hidden tabs elements heights. So the hidden tab's heights are correct. I would strongly advise using the angular version of bootstrap instead of the generic one. That way everything (events) will be in the control of angular.

https://angular-ui.github.io/bootstrap/

edit: this maybe useful for understanding digest cycle triggering and callbacks outside angular : http://school.codecraftpro.com/courses/angularjs-1x-fundamentals/lectures/392422

edit2: also useful https://scotch.io/tutorials/how-to-correctly-use-bootstrapjs-and-angularjs-together

like image 144
dekztah Avatar answered Nov 17 '22 07:11

dekztah