2016-04-01 14 views
5

Sto provando a disegnare una mappa in un bambino flessibile che occupa spazio rimanente.Render map leaflet after flexbox calcola height

Ho un paio di intestazioni in cima al contenuto principale, e uno dei banner è a volte nascosto/rimosso, quindi sto usando flexbox in modo che l'intestazione possa andare via senza alterare la posizione degli altri elementi. I. E questo non funziona bene quando utilizzo le posizioni assolute.

Il mio problema è che sembra che il volantino calcoli la finestra delle mappe prima che Flexbox abbia calcolato l'altezza per la mappa div.

Esempio:

Ecco uno screenshot del volantino pensando l'altezza mappe è più piccolo di quanto dovrebbe essere.

enter image description here

Se controllo l'altezza elementi che sia corretto. Inoltre, se inserisco un timer e impone il volantino per invalidare la dimensione della mappa, la mappa viene nuovamente visualizzata all'altezza corretta.

HTML:

<body> 
    <div class="header"> 
     Header 
    </div> 

    <div class="banner"> 
     Banner 
    </div> 

    <main class="main"> 
    <div class="nav"> 
     <strong>Navigation</strong> 
    </div> 

    <div id="map" class="map-content"></div> 
    </main> 


    <script src="script.js"></script> 
    </body> 

CSS:

html, body { 
    height: 100%; 
    width: 100%; 
    display: flex; 
    flex-direction: column; 
} 

.header { 
    height: 50px; 
    background-color: grey; 
    color: white; 
} 

.banner { 
    height: 50px; 
    background-color: lightgrey; 
    color: white; 
} 

.main { 
    display: flex; 
    flex: 1 1 auto; 
    flex-direction: row; 
} 

.map-content { 
    flex: 1 1 auto; 
} 

.nav { 
    background-color: #2A3D4A; 
    color: white; 
    width: 200px; 
} 

EDIT:

ho riprodotto il problema in un Plunk, evviva! Tuttavia, ancora non so esattamente cosa sta succedendo. Il problema si verifica solo quando includo ngAnimate nella mia applicazione. Non importa se uso ngAnimate o no.

Ecco il plunk che è rotto. Alla prima pagina di caricamento la mappa va bene. Fai clic sul link about, quindi torna alla mappa. Si noti che quando si torna indietro, solo circa la metà della mappa viene caricata. Registro l'altezza alla console Quando navighi lontano dalla mappa e ritorni sempre a circa metà delle dimensioni.

Che cosa fa l'animazione angolare per fare in modo che l'elemento diventi mezzo per dimensione per una frazione di secondo? Si tratta di un bug in angolare?

http://plnkr.co/edit/dyBH1Szo3lIEWajKqXWj?p=preview

+0

La dimensione di '# map' cambia appena si fa clic su 'about' come mostrato in questo plunker: http://plnkr.co/edit/NRTW4TL29yc36omsbJ9M?p=preview – sqsinger

+0

corretto. Buona scoperta E se non applico ngAnimate nella mia app la mappa il div non è più disponibile nella pagina about. Sembra sbagliato, perché il div è in agguato su una nuova rotta quando eseguo l'iniezione angolare nella mia app? – lostintranslation

risposta

1

A cura plunkr: http://plnkr.co/edit/pIg9HKwkl0Bfhk4N3wQX?p=preview

cercare di "invalide" la mappa in questo modo:

app.directive('leaflet', ['$document','$timeout', function($document,$timeout) { 

    function controller() { 
    console.log('in leaflet directive controller'); 

    var element = $document.find('#map'); 
    console.log('main container height: ' + element[0].offsetHeight); 

    var map = L.map('map',{crs: L.CRS.EPSG4326}).setView([0,0], 4); 
    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); 

    // the timeout wait the view to render 
    $timeout(function() { 
     // this rebuild the map 
     map.invalidateSize(); 
    }, 0); 
    } 

    return { 
    template: '<div id="map" class="map-content"></div>', 
    controller: controller, 
    replace: true 
    } 

}]); 
+0

Questa è un'opzione, ma una soluzione alternativa nel migliore dei casi. Perché include ngAnimate che fa sì che il div non vada via e, quindi, cambiando le dimensioni quando vado su un'altra rotta. – lostintranslation

+0

Da quello che so, ho riscontrato un problema con il volantino quando le mappe sono nascoste e poi visualizzate (con css come in fisarmonica per esempio). Questa è l'unica soluzione che ho trovato. Forse ngAnimate nasconde/mostra il div senza ricostruirlo. Seguo il tuo post per vedere una soluzione migliore;) – AlainIb

5

Sembra che la mappa opuscolo ha l'altezza quando creato e allora avete bisogno di chiamare .invalidateSize() se l'altezza cambia. Nella documentazione per il foglio illustrativo è indicato Make sure the map container has a defined height, for example by setting it in CSS (vedere http://leafletjs.com/examples/quick-start.html). Dato che non stai impostando l'altezza esplicitamente ma invece hai la regola css position: absolute; top:0; bottom: 0; left: 0; right: 0; è un po 'dubbia.

Credo che il problema è che quando si include ngAnimate ha un effetto sugli elementi con le proprietà transition e in qualche modo l'altezza corretta non viene vista dall'opuscolo nel tempo. Penso che dovrai utilizzare una soluzione alternativa, ad es.rilevare un cambiamento di altezza e chiamando .invalidateSize()

Prova ad aggiungere questo alla vostra direttiva:

link: function(scope, element) { 
    scope.$watch(function() { return element.parent().height(); }, function (val) { 
    console.log('height changed to: ' + val); 
    scope.map.invalidateSize(); 
    }); 
}, 
scope: true, 

Fai il controller impostato $scope.map = L.map('map',{crs: L.CRS.EPSG4326}).setView([0,0], 4); così l'oggetto opuscolo mappa è sul campo di applicazione, e rimuovere le regole CSS che hai sul .map-content

+0

E puoi trovare il risultato plnkr qui: http://plnkr.co/edit/5UNWYJH76Xo7zwE8UOD7?p=preview –

2

Ho avuto un problema simile. Quello che stava accadendo è che mentre le direttive stavano caricando, una funzione di post-link calcolava il clientHeight di un elemento div. Il div riempie lo spazio rimanente con il flex. Ma era sempre fuori da una certa quantità. L'ho rintracciato in modo angolare chiamando il link post prima che tutti i partial parziali fossero stati recuperati dal server web. Un'altra direttiva era ancora in attesa sul suo urlTemplate, e una volta entrata in vigore, quella direttiva ha causato un altro div a cambiare altezza.

Se ho appena impostato un intervallo di tempo sufficiente, ha risolto il problema. Inoltre, se trasmetto un evento dal div ritardato e lo aspetto prima di calcolare l'altezza, questo aggira anche il problema.

Non riuscivo a trovare un modo semplice per dire quando tutti i modelli erano stati caricati e tutte le direttive avevano fatto il loro lavoro manipolando il DOM. Le priorità della direttiva non hanno fatto assolutamente nulla per cambiare l'ordine delle cose.

Osservare la sequenza di eventi nel browser e verificare se non si tratta di un modello parziale che arriva in ritardo e che elimina i tempi in modo che i calcoli non vengano eseguiti esattamente quando si chiede che vengano eseguiti.