Search code examples
javascriptgoogle-mapsbackbone.jsbackbone-views

Pass the view that manages something to the second view - Backbone


I have two views, one for rendering google maps and another to render list of events that contain's latitude and longitude to render markers on the view that contains google maps. When I try to pass the view that manages the map to the initialize method of the second view and save an instance reference, display in console the following error:

enter image description here

Here's my code

app.js

var ev = new Application();

ev.Router = Backbone.Router.extend({

    routes: {
        "": "home",
        "evento/:id" : "evento"
    }, 

    home: function(){
        var mapView = new ev.views.Home();
        $('#home').html(mapView.el);
        $('#rightcolumn').html(new ev.views.Home_Eventos(mapView).el);
    },

    evento: function(id){
        $('#rightcolumn').html(new ev.views.Evento(id).el);

    }
});

$(document).on('ready', function() {
    // Load HTML templates for the app
    ev.templateLoader.load(['shell', 'home', 'home_list_eventos', 'evento'], function () {
        ev.shell = new ev.views.Shell({el: "#shell"});
        ev.router = new ev.Router();
        Backbone.history.start();
    });
});

home.js

ev.views.Home = Backbone.View.extend({
    map: 'null',
    initialize: function(){
        this.template = _.template(ev.templateLoader.get('home'));
        this.render();
    },

    initMap: function(){

        var that = this;
        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                var pos;
                pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                var infowindow = new google.maps.InfoWindow({
                    map: that.map,
                    position: pos
                });

                that.map.setCenter(pos);
            });
        }

        var mapOptions = {
            zoom: 12,
        };
        that.map = new google.maps.Map(that.$el.find('#map_canvas')[0],mapOptions);
        google.maps.event.addDomListener(window, "resize", function() {
            var center = that.map.getCenter();
            google.maps.event.trigger(that.map, "resize");
            that.map.setCenter(center); 
        });
    },

    render: function(){

                this.$el.html(this.template());
                this.initMap();
                return this;    
    }
});

home_events.js

ev.views.Home_Eventos = Backbone.View.extend({
    initialize: function(mapView){
        this.template = _.template(ev.templateLoader.get('home_list_eventos'));
        this.mapView = mapView;
        console.log(this.mapView.map);
        this.render();
        console.log("sou inicializado");
    },

    render: function(){

        var that = this;
        var imagens = new ev.models.ImagemCollection();
        imagens.fetch({
            success: function(){
                that.$el.html(that.template({imagens: imagens.models}));


                var marcadores = imagens.models;
                setTimeout(function() {
                _.each(marcadores, function(marcador){
                    var myLatlng = new google.maps.LatLng(marcador.get('latitude'),marcador.get('longitude'));
                    var marker = new google.maps.Marker({
                        position: myLatlng,
                        map: map,
                    });

                });
                    }, 6000);

                return that;
            }
        });
    }

});

Templates of document: shell.html:

<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
    ...
</nav>

<div class="wrapper-home" id="home">

</div><!--/.fluid-container-->

home.html:

<div id="leftcolumn">
    <div id="map_canvas"></div>
    </div>
    <div id="rightcolumn">
        <div class="row">
        <div class="col-xs-5 coluna-input">
            <form role="form">
                <div class="form-group">
                    <label for="pesquisar">Pesquise</label>
                    <input type="text" class="form-control" id="pesquisar" placeholder="Pesquisar...">
                </div>
                <div class="form-group">
                    <label for="quando">Quando</label>
                    <input type="text" class="form-control" id="quando" placeholder="Quando">
                </div>
            </form>
        </div>

        <div class="col-xs-5 coluna-input">
            <form role="form">
                <div class="form-group">
                    <label for="pac-input">Onde</label>
                    <input type="text" class="form-control" id="pac-input" placeholder="Onde">
                </div>
                <div class="form-group">
                    <label for="genero">Género</label>
                    <input type="text" class="form-control" id="genero" placeholder="Genero">
                </div>
            </form>
        </div>

        <div class="col-xs-5 coluna-input">
            <button id="search" type="button" class="btn btn-primary botao">Pesquisar</button>
        </div>

        <div class="col-xs-5 coluna-input">
            <button type="button" class="btn btn-danger botao">Mais Filtros</button>
        </div>

    </div>
    <hr class="linha"/>

    <div class="row" id="lista">
        <div class="table">
            <tbody>
                <% _.each(imagens, function(imagem){  %>
                <tr>
                    <div class="col-xs-5 coluna-input">
                        <img src="<%= imagem.get('imagem') %>" class="img-responsive  back" alt="Responsive image">
                        <a href='#evento/<%= imagem.get('id') %>' class="btn btn-primary">Ver Mais</a>
                    </div>
                </tr>
                <% }); %>
            </tbody>
        </div>

    </div>
    </div>

Solution

  • You initialize new ev.views.Home_Eventos(mapView) as a parameter to $.html(), which is fine except that the render function in that view is 'async' because of the fetch in it. So the el it returns should be an empty <div> since the success callback doesn't return until after the initialize is complete.