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.

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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!
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"
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;
    ...
]);

3 Comments

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?
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.
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.
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.

1 Comment

Great read but not really bound to the subject of keeping a rendered state of an element. Thanks though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.