4 Replies Latest reply: Jul 30, 2017 8:40 AM by Darius Pranskus RSS

    How to make Qlik Sense extensions built with AngularJS re-render on resize or when the data changes?

    Karthikeyan Default

      When using plain JavaScipt, we write the rendering logic inside the 'paint' function and it gets executed and the view gets re-rendered, whenever we resize the element, or when the data changes on applying filters.


      But when using AngularJS controller, re-rendering is not happening in both the cases. I've to refresh the browser to see the changes take effect.


      Please help me with this.

        • Re: How to make Qlik Sense extensions built with AngularJS re-render on resize or when the data changes?
          Stefan Walther

          Angular uses double-way binding, so there is no re-paint, AngularJS takes care of updating the corresponding DOM elements. Maybe this article helps as a starting point:

           

          The Angular Way: Basics | qliksite.io

           

          Hope this helps.

          Regards

          Stefan

          • Re: How to make Qlik Sense extensions built with AngularJS re-render on resize or when the data changes?
            Darius Pranskus

            I had the same issue, I was able to find a workaround. Not sure if this is the best solution or not, but it worked for me.

             

            What I wanted was to detect when the following events are triggered:

             

            1. Browser window has been resized

            2. Extension element has been resized

            3. Layout/properties of my extension has been modified

             

            The first might be achieved by subscribing to window resize event. With the jquery it is easy - just put it in your angular controller

             

            $(window).on("resize", function(event) {
                console.log("window.resize");
                console.dir(event);
                // Do whatever you want
            });
            

             

            Other two were a bit trickier.

             

            To sort the second issue I did the following:

             

            I created a dummy invisible component in my extension definition, injected a $rootScope into the controller and then created an event watcher:

            
            

             

            refresh: {
                component: {
                    template: "<span></span>",
                    controller: ["$rootScope", "$scope", function ($rootScope, $scope) {
                        $scope.$on("layoutchanged", function (event, data) {
                            $rootScope.$broadcast("myLayoutChanged", data);
                        });
                    }]
                }
            }
            

             

            Then in the main component controller I added another watcher:

            $scope.$on("myLayoutChanged", function (event, data) {
                console.log("myLayoutChanged");
                console.dir(event);
                console.dir(data);
                // Do wahterver you want
            });
            

             

            I tried to watch on the "layoutchanged" message directly on the main controller, but it did not work. Possibly that the message was not propagated to it.

             

            The solution to the third issue was to inject a $rootScope into main controller, add to the layout object a function to return the $rootScope object and then use it in the onResize() (non angularjs) event to broadcast a message which can be then catched in the main controller:

            resize: function($element, layout) 
            {
                if (layout.getRootScope) {
                    var $rootScope = layout.getRootScope();
                    $rootScope.$broadcast("myElementResize", $element);
                }
            },
            template: ngTemplate,
            controller: ["$rootScope", "$scope", "$element", "$attrs", function ($rootScope, $scope, $element, $attrs) {
            
                $scope.layout.getRootScope = function() {
                    return $rootScope;
                }
            
                $scope.$on("myElementResize", function (event, data) {
                    console.log("myElementResize");
                    console.dir(event);
                    console.dir(data);
                    // Do whatever you want
                });
                // The rest of the controller code goes here
            
            }]