2016-12-20 11 views
0

Verzeihen Sie mir, wenn ich ein bisschen verwirrt bin, wage ich mich in meinem Programm in neue terratory und lerne, wie ich gehe. Das grundlegende Konzept, mit dem ich kämpfe:Schienen 4, Turbolinks und Kaffeeskript

In meiner Rails 4 app verwende ich Leaflet (eine JS-Bibliothek für die Zuordnung) und einige meiner eigenen Code aufrufen. Lange Rede, kurzer Sinn: Ich konnte Leaflet und Turbolinks nicht gut zusammen spielen, also lade ich für die Seiten meiner Seite, auf denen ich Leaflet, Turbolinks deaktiviert habe, Seite-spezifische Coffeescript.

Ich habe jetzt entschieden, dass ich einen Zurück-Button hinzufügen möchte. Die Verwendung würde folgendermaßen aussehen: Auf einer Seite, die Leaflet verwendet, kann der Benutzer auf ein Stück der Karte klicken und auf eine Seite mit Turbolinks (falls es darauf ankommt) zugreifen. Von der Turbolinks-Seite aus habe ich eine Zurück-Schaltfläche, mit der Sie zurück zur Leaflet-Map gelangen.

Wenn ich jedoch zurück zur Leaflet-Seite komme, wird mein coffeescript entweder nicht ausgeführt oder wird zur falschen Zeit ausgeführt (ich bekomme mehrere Fehler, die beim ersten Mal nicht vorhanden waren). Ich vermute, dass ich zu Beginn des Coffeescript ein weiteres Event hinzufügen oder ein anderes Event wählen müsste, aber ich bin mir nicht sicher, was es sein soll.

Ich bin in keiner Weise daran gebunden, Turbolinks nicht auf der Leaflet-Seite zu verwenden, wenn Sie einen Vorschlag haben, wie es funktioniert und es hilft, den Zurück-Button zum Laufen zu bringen. :)

_navbar.html.erb

<li><%= link_to("By grid", grid_path, data: {turbolinks: false}) %></li> 

grid.html.erb

... code for layout goes here ... 
<% content_for :header do %> 
    <%= javascript_include_tag "leaflet" %> 
<% end %> 
<% content_for :javascript do %> 
    <%= javascript_include_tag "leaflet-maps/#{filename}" %> 
<% end %> 

leaflet-maps/grid.coffee

$ -> 
    document.addEventListener 'page:restore', -> 
    app.init() 
    return 
... rest of coffeescript goes here ... 
... here is how the link is getting called 
    layer.on 'click', (e) -> 
    window.location.href='/show?grid='+feature.id 
    return 

show.html.erb

aktualisieren

grid.coffee - in voller Coffeescript-Code

ready = -> 
#-------------------------------------------------- 
# Build tooltip with plant name 
#-------------------------------------------------- 
    onEachFeature = (feature, layer) -> 
    if feature.properties and feature.properties.grid_name 
     layer.bindTooltip feature.properties.grid_name 
     layer.on 'click', (e) -> 
     window.location.href='/show?grid='+feature.id 
     return 
    return 

#-------------------------------------------------- 
# Variables 
#-------------------------------------------------- 
    L.Icon.Default.imagePath = '/assets' 
    gridStyle = { 
    "color": "#ff7800", 
    } 
    neCorner = L.latLng([47.635103, -122.320525]) 
    swCorner = L.latLng([47.634083, -122.321129]) 


#-------------------------------------------------- 
# Set view and load Google Maps 
#-------------------------------------------------- 
    map = L.map("map", zoomSnap: .25) 
    map.fitBounds([swCorner, neCorner]) 
    map.invalidateSize(false) 
    map.options.maxZoom = 22 
    map.options.bounceAtZoomLimits = true 
    googleLayer = L.gridLayer.googleMutant(type: 'roadmap').addTo(map) 
    map.addLayer googleLayer 

#-------------------------------------------------- 
# Get Ajax data 
#-------------------------------------------------- 
    $.ajax 
    dataType: 'text' 
    url: 'grid.json' 
    success: (data) -> 
     L.geoJSON(JSON.parse(data), style: gridStyle, onEachFeature: onEachFeature).addTo map 
    error: -> 
     alert "Failed to load AJAX data" 

document.addEventListener 'turbolinks:load', ready() 
document.addEventListener 'DOMContentLoaded', ready() 

Antwort

1

So gibt es zwei Orte, wo man außerhalb der Spur gehen könnte. Die erste ist hier:

$ -> 
    document.addEventListener 'page:restore', -> 
    app.init() 

Was dies sagt, ist ... „wenn die Webseite des DOMContentLoaded Ereignis sendet, dann, wenn etwas anderes das Ereignis page:restore aussendet, dann, meinen JavaScript-Code ausgeführt werden.“

Beginnen wir mit DOMContentLoaded. Dies ist ein Ereignis, das von Browsern standardmäßig ausgegeben wird und das vom jQuery-Framework zum Auslösen von Ereignis-Listenern verwendet wird. You can read more about jQuery's .ready() function here.

Die page:restore Veranstaltung ist kein standard emittiert Ereignis, sondern war a custom event used in Turbolinks Classic (Version < 5.0, Stand Februar 2016 veraltet), die ich glaube, Sie verwenden, da Sie Rails erwähnt 4.

So oder so, Es ist wahrscheinlich nicht das, was Sie tun möchten, wenn Sie beide Listener aufeinander stapeln. Was Sie tun könnten, um eine Funktion zu definieren, die sowohl auf ready als auch auf page:restore läuft ...

function ready() { 
    // All of the setup you want to do... 
} 

document.addEventListener("turbolinks:load", ready()); 
document.addEventListener("DOMContentLoaded", ready()); 

(Sorry, ich merke, du bist Coffeescript zu schreiben. Das ist nicht meine Marmelade. Ich hoffe, meine JavaScript ist OK ...)

Das eine ist. Ich sehe eine weitere Möglichkeit zur Verbesserung.

layer.on 'click', (e) -> 

Was Sie sagen ist „wenn das Dokument geladen wird, für Klicks auf dem layer Objekt zu hören, und dann diese Sache tun.“

Ich bin nicht genau sicher, was layer ist, und wenn es Leaflet-spezifische ist, werde ich wahrscheinlich nicht in der Lage sein, Ihnen zu helfen. Allerdings gibt es tatsächlich eine widerstandsfähigere Möglichkeit, dies zu schreiben.

$(document).on("click","layer", function() { 
    // do things with the layer 
}); 

Dies mag identisch erscheinen, aber es gibt einen feinen Unterschied. Es heißt "jedes Mal wenn ich auf das Dokument klicke, wenn ich auch zufällig auf eine Ebene klicke, mache das Ding."

Dies ist widerstandsfähiger, weil Ihre Zeile JavaScript immer die document finden kann, wenn es ausgeführt wird. Wenn Ihre layer bis zu dem Zeitpunkt, an dem diese Codezeile ausgeführt wird, nicht gerendert wurde, werden diese Klicks niemals erfasst.

Happy Java Scripting! :)

+0

das sind beide sehr hilfreiche Kommentare. :) Ich habe meinen Code überprüft und es stellt sich heraus, dass ich TurboLinks 5 verwende. Gibt es einen besseren Weg? Außerdem habe ich meinen vollständigen coffeescript-Code hinzugefügt, weil ich nicht sicher bin, wie ich die Layer-Sache ändern kann. Hier ist ein [link] (http://leafletjs.com/reference-1.0.2.html#layer) zu Leaflet-Dokumenten für die Ebene (falls sie helfen). – Ben

Verwandte Themen