4

I'm making a web app where users can view objects on a map, press a marker and go to a new view with information. From that view they can traverse deeper, into more information.

Something like:

  • /map
  • /tree/{treeid}
  • /tree/{treeid}/information/{informationid}

I know how to keep the actual model state when traversing between routes/states. The problem is that I don't want to recalculate the entire map (with markers and everything) when I go back in the browser history. In other words, I want to keep the rendered state of /map when traversing further.

This can easily be achieved by using search parameters instead of routes on /map (ie. /map?treeid=10) and disable reload on search, and doing ng-hide="treeid" on the map object and ng-show on the tree-info object.

My question is if there is a better, more appropiate way of doing this in angular?

Thanks in advance.

PerMafrost
  • 509
  • 3
  • 18

3 Answers3

2

Addressing your "recalculate the entire map" question, one way to resolve this is to draw the Google Map at the same level as your ng-view, and shift it out of the view to hide it.

Here is a plunker illustrating how this would work:
http://plnkr.co/edit/wsjYoG2uXxYxXTmWdFGh?p=preview

Notice how I intentionally left a part of the map on screen when hiding to show that it does not redraw as you change the route.

marcoseu
  • 3,892
  • 2
  • 16
  • 35
  • This was a great idea, I had not thought of it. It really solves the problem without having to do some "dirty" solution. Thank you for the great example as well! – PerMafrost Mar 05 '14 at 09:46
  • May I suggest that you change the title of your question to something like "How to prevent Google Map redraw when changing route in AngularJS" – marcoseu Mar 05 '14 at 10:55
0

You could create a dedicated service to store the data. As services are singleton, the data would be shared amongst your views and controllers. Something like this:

angular.module('myApp').factory('GlobalService', [
    function() {
        var _this = this;
        _this._data = {
            user: window.user,
            authenticated: !! window.user
        };

        return _this._data;
    }
]); 


angular.module('myApp').controller('FooController',
    ['$scope', 'GlobalService',
    function ($scope, GlobalService) {
    $scope.global = GlobalService;
    $scope.global.bar = someData;
    ...
]);
Pascal Le Merrer
  • 5,883
  • 20
  • 35
  • But this would only allow me to keep the model state, not the actual rendered state of the view, right? To render a (eg) custom google map with thousands of markers, centered on the correct position takes some time, no matter if the model is ready. So instead of deleting the content from ng-view on route change, is it possible to just hide it or is that bad practice or impossible? – PerMafrost Mar 05 '14 at 07:55
  • You're right, it will just keep the model. For the rendered state of the view, you could try to detach it from it's parent using angular.element and attach it to a dom point outside of the ngview, before leaving the view, and then reattach it to the ngview content when entering a view. It's a wild guess, I have no idea of the impact on Angular's internal. – Pascal Le Merrer Mar 05 '14 at 08:01
  • Thank you for the input. I've accepted marcoseu's answer as it solved the problem in a simple manner and without having a bad impact on the rest of the system. – PerMafrost Mar 05 '14 at 09:44
0

This looks like a useful read: AngularJS Performance Tuning for Long Lists. It details recommendations and pitfalls to avoid when rendering large/complex data structures.

seanhodges
  • 17,426
  • 15
  • 71
  • 93