Google Map not rendering correctly after first view with Backbone.js

Asked By: Anonymous

Im creating a mobile app with Phonegap, Backbone.js, Require.js and PageSlider (https://github.com/ccoenraets/PageSlider).

I want to display a simple Google Map with a marker. The template looks like:

<div class='main-content' id='map-container'>

    <a href="geo:51.903679,-8.468274">
        <div id="map-canvas"></div>
    </a>

</div>

Here is the view:

define(function (require) {

"use strict";

var $                   = require('jquery'),
    _                   = require('underscore'),
    Backbone            = require('backbone'),
    tpl                 = require('text!tpl/Map.html'),
    side_nav                = require('text!tpl/SideNav.html'),
    template = _.template(tpl),
    map, myLatlng, mapOptions, marker;


return Backbone.View.extend({

    initialize: function () {          
        this.render();      
    },

    initMap: function () {

         myLatlng = new google.maps.LatLng(51.903679, -8.468274);

         mapOptions = {
            center: myLatlng,
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

            map = new google.maps.Map(this.$el.find('#map-canvas')[0],
                                      mapOptions);


         marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title: 'Christians Brothers College Cork'
        });

    },

    render: function () {
        this.$el.html(template({side_nav:side_nav}));
        this.initMap();       
    },


});

});

Here is a link to the app. When you click on “location”, the map renders perfectly. But when you navigate anywhere else, then back to location, only a tiny portion of the map can be seen in the top left hand corner.

I tried doing, which was suggested here:

google.maps.event.trigger(map, 'resize').

but to no avail. Any ideas?


Solution

Answered By: Anonymous

Your view works on a node not appended to the DOM, thus without size, a situation Google Map is not very fond of. It is your router, via PageSlider, that does append the node after your render function has occurred.
Here is a demo of your predicament : http://jsfiddle.net/3C7g3/

You have several options to solve it:

  • call google.maps.event.trigger(map, 'resize') after the node is inserted into the DOM (this bit of code corresponds to your router entry for the map)
    // assuming you stored the map object in your view
    require(["app/views/Map"], function (Map) {
        var view = new Map();
        slider.slidePage(view.$el);
        google.maps.event.trigger(view.map, 'resize');
     });
    

    http://jsfiddle.net/3C7g3/1/

  • insert the node into DOM before calling render. In your case, that probably means removing render from the view.initialize and calling view.render after container.append(page); in your slidePageFrom method.

    http://jsfiddle.net/3C7g3/2/

  • a more hackish way would be to temporarily add the element to the DOM, apply Google Maps, and then remove it from the DOM

    initMap: function () {
        // assuming a temp class that hides the element. For example,
       // .temp {position: absolute; visibility:hidden; }
        this.$el.addClass('temp');
        $('body').append(this.$el);
        // ...
        this.$el.remove();
        this.$el.removeClass('temp');
    }
    

    http://jsfiddle.net/3C7g3/3/

techinplanet staff

techinplanet staff


Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno