2016-07-19 20 views
0

リーフレットを使用してクライアントサイトのマップを表示するページを開発しています。ページは最初に、IDの名前、緯度、長さなどのマップの詳細をロードします。ロードはajaxを介して非常に単純なC#ページに格納されているprocを実行し、レコードセットをJSONとして返します。jQuery ajaxコールは、ステップ実行時にのみ動作します

マップがロードされると、マップ上のマーカーをクリアしてプロットする2番目のajax呼び出しがあります。これは、車両の詳細を返す同様のC#ページです。このajax呼び出しはsetInterval(function())呼び出しに設定され、x秒ごとに繰り返されます。

ページを正常に実行すると、何も正しく読み込まれません。 firefoxでデバッガを調べると、最初のajax呼び出しが未定義に戻っていることがわかります。ブレークポイントを追加して何が起こったかを見るためにステップスルーすれば、それは機能します。ブレークポイントを削除すると失敗します。

私はここで間違っていますか?

メインHTMLファイル

<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"> 

スクリプトブロック

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> 

追加JSファイル

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

[非同期呼び出しからの応答を返すにはどうすればよいですか?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-呼び出し) – Andreas

+0

ステップ実行時に異なる動作に気付くと、非同期要求が別の順序で処理されていることがよくあります。上記の@アンドレアスで述べたように、解決策はしばしば約束です。 – smoksnes

+0

私の理解では、jQueryと.done()と.fail()イベントを使用すると、その非同期待機問題が回避されます。あなたのコードは応答するまで起動しません。 $アヤックス({// オプション }) の.done(機能(結果){}) .fail(機能(XHR、ステータス、エラー){}) – Hecatonchires

答えて

0

私はjQueryのときを(使用して終了)した後、()

最初の呼び出しは、ページのロード時に一度起こったとして行う最初の呼び出しで私のAJAXを置く
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 
    }); 
}); 

は、合わなかった、そして第二は、すべて発生しましたリフレッシュ秒。

0

他の質問にリンクするのではなく、あなたを助けるために:

Ajaxは非同期です。これは、呼び出しを開始し、他のコードを実行するために読み込み中に途切れた後、読み込みが終了してコールバックを実行することを意味します。

第2のajax呼び出しは、第1のajaxが完了するのを待ってから、私が推測しています。あなたがする必要があるのは、呼び出しを1番目のajaxの成功コールバックに移動するか、2番目の呼び出しをajax:successハンドラにバインドする必要があります。

+0

私は(の.doneを使用しています)と私が思った正しいjQueryの方法である.fail()イベント – Hecatonchires

+0

[重複する質問はどのように処理するのですか?](http://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled) – Andreas

+0

はい、あなたはそれらの機能を持っています。しかし、2つのajaxコールがあるという点では、2番目のajax呼び出しは、最初の.done()内で呼び出される必要があります。または、コールバック地獄が気に入らない場合は、IIFEを使用します。 – gcoreb

関連する問題