2016-07-19 6 views
0

Ich entwickle eine Seite mit Leaflet, um eine Karte für eine Kunden-Website anzuzeigen. Die Seite lädt zuerst die Details der Karte - name, lat, long usw. basierend auf einer ID. Die Ladung erfolgt über Ajax zu einer sehr einfachen C# -Seite, die einen gespeicherten Prozess ausführt und das Recordset als JSON zurückgibt.jQuery Ajax Anruf funktioniert nur, wenn ich durch es gehe

Sobald die Karte geladen ist, gibt es einen zweiten Ajax-Aufruf, der Marker auf der Karte löscht und plottet. Dies ist eine ähnliche C# -Seite, die Fahrzeugdetails zurückgibt. Dieser Ajax-Aufruf wird dann in einen Aufruf setInterval (function()) gesetzt, um alle x Sekunden zu wiederholen.

Wenn ich die Seite normal laufe, wird nichts richtig geladen. Beim Durchsuchen des Debuggers in Firefox kann ich sehen, dass der erste Ajax-Aufruf undefiniert zurückgegeben wurde. Wenn ich einen Haltepunkt hinzufüge und durchschaue, was passiert, funktioniert es. Wenn ich den Haltepunkt entferne, schlägt es fehl.

Was mache ich hier falsch?

Haupt HTML-Datei

<head> 
    <meta http-equiv="x-ua-compatible" content="IE=11"> 
    <meta charset="utf-8" /> 
    <meta http-equiv="refresh" content="3600"> 
    <title>Map Viewer</title> 
    <link rel="stylesheet" type="text/css" href="/Content/themes/base/all.css" /> 
    <link rel="stylesheet" type="text/css" href="/Content/Site.css" /> 
    <link rel="stylesheet" type="text/css" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" /> 

    <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png"> 
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"> 
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"> 

    <script type="text/javascript" src="/Scripts/jquery-3.0.0.min.js"></script> 
    <script type="text/javascript" src="/Scripts/jquery-ui-1.11.4.min.js"></script> 
    <script type="text/javascript" src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script> 
    <script type="text/javascript" src="/Scripts/leaflet-providers.js"></script> 
    <script type="text/javascript" src="/Scripts/leaflet-tracksymbol.js"></script> 
    <script type="text/javascript" src="/Scripts/leaflet-tracklayer.js"></script> 

    <script type="text/javascript" src="/Scripts/ctrack-clearybros.js"></script> 

    <meta name="viewport" content="width=device-width" /> 
</head> 
<body > 
<h1 id="pageTitle"></h1> 
<div id="errorText"></div> 
<div id="map"></div> 

<script id="mapScript" type="text/javascript"> 

Script Block

var mapDetails; 
    var mapId = 1; 
    var reloadTime = 15 * 1000; //15 seconds 
    //var w = $(window).width(); 
    //var h = $(window).height(); 

    mapDetails = getMapDetails(mapId); 
    console.debug("Map details retrieved"); 
    console.debug(mapDetails); 
    //$("#map").width(w); 
    //$("#map").height(h); 
    $("#pageTitle").text(mapDetails.mapTitle); 

    var map = new L.Map("map", { 
     center: mapDetails.mapCenter, 
     minZoom: 16, 
     maxZoom: 16, 
     zoom: 16, 
     reuseTiles: true, 
     unloadInvisibleTiles: true 
    }); 
    console.debug("Map Created"); 
    //console.debug(map); 

    var appId = "snip"; 
    var appCode = "snip"; 

    //using plugin 
    var tilesLayer = new L.tileLayer.provider("HERE.terrainDay", { 
     attribution: "Event Data &copy; <a href=\"http://www.ctrackonline.com.au/\">Ctrack Australia</a> &#151; Map Data &copy; <a href=\"http://www.here.com\">HERE maps</a>", 
     app_id: appId, 
     app_code: appCode, 
     subdomains: '1234', 
     mapID: 'newest', 
     base: 'aerial', 
     maxZoom: 20, 
     type: 'maptile', 
     language: 'eng', 
     format: 'png8', 
     size: '256' 
    }); 
    tilesLayer.addTo(map); 
    console.debug("tileLayer Created"); 
    //console.debug(tilesLayer); 

    map.removeControl(map.zoomControl); 
    map.dragging.disable(); //disable map panning 
    map.doubleClickZoom.disable(); //disable click to recenter 
    map.touchZoom.disable(); 
    map.scrollWheelZoom.disable(); 
    map.boxZoom.disable(); 
    map.keyboard.disable(); 
    console.debug("Map options set"); 

    var unitLayer = new L.FeatureGroup(); 
    unitLayer.addTo(map); 


    populateUnitLayers(mapId) //prime the pump before the setInterval fires 
    console.debug("Vehicle layer populated"); 
    console.debug(unitLayer); 
    //setInterval(function() { 
    // populateUnitLayers(mapId) //called every reloadTime seconds 
    //}, reloadTime); 

</script> 


<div id="ajaxLoadingHolder"> 
    <div id="ajaxLoading"><img src="/Content/images/ajax-loader.gif" /></div> 
</div> 

Zusätzliche JS-Datei

function getMapDetails(mapId) { 
    var _mapTitle; 
    var _mapLatitude; 
    var _mapLongitude; 
    var _mapCenter; 

    var JsonUrl; 
    if (window.location.pathname == "/ClearyBros.cshtml") { JsonUrl = "/JSON/GetDetailForLocation"; } 
    if (window.location.pathname == "/CtrackMaps/ClearyBros.cshtml") { JsonUrl = "/CtrackMaps/JSON/GetDetailForLocation"; } 

    $.ajax({ 
     method: "GET", 
     url: JsonUrl, 
     processData: true, //means data sent as querystring 
     dataType: "json", //,"text" 
     data: { mapId: mapId }, 
     timeout: 60000 
    }) 
    .done(function (results) { 
     if (jQuery.isEmptyObject(results)) { 
      console.error("Map details are blank"); 
     } 
     else { 
      console.debug("Map details are not blank"); 
      console.debug(results); 
     } 
     $.each(results, function (index, result) { 
      _mapTitle = result.Name; 
      _mapLatitude = result.Latitude; 
      _mapLongitude = result.Longitude; 
      _mapCenter = new L.LatLng(_mapLatitude, _mapLongitude); 
     }); 
    }) 
    .fail(function (xhr, status, error) { 
     console.error("Failed to load map details"); 
     if (status == "timeout") { 
      var errorText = "Timeout reached loading map details."; 
      displayError(errorText); 
     } 
     else { 
      var errortext = "Error state \"" + status + "\" occured loading map details. \n" + error; 
      displayError(errorText); 
     } 
    }); 

    var obj = { 
     mapTitle: _mapTitle, 
     mapLatitude: _mapLatitude, 
     mapLongitude: _mapLongitude, 
     mapCenter: _mapCenter 
    }; 

    return obj; 
} 

function populateUnitLayers(mapId) { 
    // set all our marker default values here. This doesnt get added to a layer. 
    var trackSymbolDefault = new L.trackSymbol(new L.LatLng(0.0, 0.0), { 
     trackId: 0, 
     fill: true, 
     fillColor: '#ffffff', 
     fillOpacity: 1.0, 
     stroke: true, 
     color: '#000000', 
     opacity: 1.0, 
     weight: 1.0, 
     speed: 0, 
     course: 0, 
     heading: 0, 
     leaderTime: 0 
    }); 

    var JsonUrl; 
    if (window.location.pathname == "/ClearyBros.cshtml") { JsonUrl = "/JSON/GetUnitsForLocation"; } 
    if (window.location.pathname == "/CtrackMaps/ClearyBros.cshtml") { JsonUrl = "/CtrackMaps/JSON/GetUnitsForLocation"; } 

    unitLayer.clearLayers(); 
    //unit0Layer.clearLayers(); 
    //unit1Layer.clearLayers(); 
    //unit2Layer.clearLayers(); 

    $("#error-text").hide(); 

    $.ajax({ 
     method: "GET", 
     url: JsonUrl, 
     processData: true, //means data sent as querystring 
     dataType: "json", //"text", 
     data: { mapId: mapId }, 
     timeout: 60000 
    }) 
    .done(function (results) { 

     $.each(results, function (index, result) { 
      var marker = createUnitMarker(result, trackSymbolDefault); 
      if (marker.options.speed == 0) { 
       marker.options.color = '#cccccc'; 
       //marker.addTo(unit0Layer); 
       //unit0Layer.addTrack(marker); 
      } 
      else if (marker.options.speed > 60) { 
       marker.options.color = '#ff0000'; 
       //marker.addTo(unit1Layer); 
       //unit1Layer.addTrack(marker); 
      } 
      else { 
       marker.options.color = '#ffff00'; 
       //marker.addTo(unit2Layer); 
       //unit2Layer.addTrack(marker); 
      } 
      //marker.addTo(map); 
      marker.addTo(unitLayer); 
     }); 
    }) 
    .fail(function (xhr, status, error) { 
     console.error("Failed to load vehicle details"); 
     displayError("Error getting data while loading vehicle positions"); 
     if (status == "timeout") { 
      //alert("Timeout reached."); 
      displayError("Timeout reached loading map details"); 
     } 
     else { 
      //alert("Error state \"" + status + "\" occured loading vehicle positions. \n" + error); 
      var errorText = "Error state \"" + status + "\" occured loading vehicle positions."; 
      displayError(errorText); 
     } 
    }); 
} 

function createUnitMarker(result, defaults) { 
    var _marker; 
    const kphToMph = 0.621371; 

    var _latlng = new L.LatLng(result.Latitude, result.Longitude); 
    var _track = result.NodeId; 
    var _speed = result.Speed * kphToMph; // Km/h to m/h 
    var _course = result.Heading * Math.PI/180.0; // Radians from north 
    var _heading = result.Heading * Math.PI/180.0; 

    _marker = new L.trackSymbol(_latlng, { 
     trackId: _track, 
     fill: defaults.options.fill, 
     fillColor: defaults.options.fillColor, 
     fillOpacity: defaults.options.fillOpacity, 
     stroke: defaults.options.stroke, 
     color: defaults.options.color, 
     opacity: defaults.options.opacity, 
     weight: defaults.options.weight, 
     speed: _speed, 
     course: _course, 
     heading: _heading, 
     leaderTime: defaults.options.leaderTime 
    }); 

    var _note = "<p><b>Unit Name:</b> " + result.UnitName + "<br /><b>Unit Desc:</b> " + result.UnitDesc + "<br /><b>Last Updated:</b> " + result.AssembledTime + "<br /><b>Speed:</b> " + result.Speed + " km/h</p>" 
    _marker.bindPopup(_note); 

    console.debug("TrackId " + _marker.options.trackId + " added"); 

    return _marker; 
} 

function displayError(message) { 
    $("#error-text").text(message); 
    $("#error-text").show(); 
} 

$(document).ajaxStart(function() { 
    $("#ajaxLoading").show(); 
}).ajaxStop(function() { 
    $("#ajaxLoading").hide(); 
}); 
+0

Mögliches Duplikat von [Wie gebe ich die Antwort von einem asynchronen Anruf zurück?] (Http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous- call) – Andreas

+0

Wenn Sie beim Durchlaufen ein unterschiedliches Verhalten bemerken, ist dies oft das Ergebnis von asynchronen Anforderungen, die in einer anderen Reihenfolge verarbeitet werden. Die Lösung verspricht oft, wie von @Andreas oben erwähnt. – smoksnes

+0

Mein Verständnis ist, dass die Verwendung von jQuery und den .done() - und .fail() - Ereignissen dieses aschetische Warteproblem vermeidet. Ihr Code wird erst ausgelöst, wenn er geantwortet hat. $ Schnipsel ({ // Optionen }) .done (function (Ergebnisse) {}) .fail (function (XHR, Status, Fehler) {}) – Hecatonchires

Antwort

0

landete ich mit bis jQuery, wenn() und dann()

var ajaxOptions = { 
    method: "GET", 
    url: JsonUrl, 
    processData: true, //means data sent as querystring 
    dataType: "json", //"text", 
    data: { mapId: mapId }, 
    timeout: 60000, 
    cache: false 
} 

$.when($.ajax(ajaxOptions)) 
.then(function (results) { 
    $.each(results, function (index, result) { 
     // do stuff with each result 
    }); 
}); 

meine Ajax in den ersten Anrufe getan Putting passen nicht, wie der erste Anruf einmal passiert beim Laden der Seite und die zweite aufgetreten jeder Sekunden aktualisieren.

0

Um Ihnen zu helfen, anstatt nur auf andere Fragen zu verlinken:

Ajax ist asynchron. Dies bedeutet, dass es den Aufruf startet, während des Ladens aus dem Weg kommt, um anderen Code auszuführen, und wenn das Laden beendet ist, kommt es zurück und führt den Rückruf aus.

Der zweite Ajax-Aufruf muss warten, bis der erste Ajax fertig ist, bevor ich rate. Was Sie tun müssen, ist, entweder den Anruf in den Rückruf des ersten Ajax zu verschieben, oder Sie müssen den zweiten Anruf an einen Ajax: Success-Handler binden.

+0

ich die .done bin mit() und .fail() - Ereignisse, die die richtige jQuery-Methode ist, dachte ich – Hecatonchires

+0

[Wie sollten doppelte Fragen behandelt werden?] (http://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled) – Andreas

+0

Ja, Sie haben diese Funktionen. Aber in Bezug auf zwei Ajax Anrufe.Der zweite Ajax-Aufruf muss innerhalb der ersten .done() aufgerufen werden, oder wenn Sie die Callback-Hölle nicht mögen, verwenden Sie IIFE. – gcoreb

Verwandte Themen