2017-09-11 39 views
-2

因此,我正在構建一個網絡應用程序,該應用程序使用Google地圖的API來顯示帶有一些標記的地圖,每次點擊標記時,應該顯示該地點的5篇文章,這些由谷歌新聞提供的,事情是,我很新的JavaScript和Web開發,我一直在嘗試幾個小時來解決這個問題,我自己,我不知道如何。我將離開我的JS文件和使用燒瓶的python文件來處理服務器請求,但我確信服務器端沒有任何問題。Google Maps API Javascript錯誤

JS:

// Google Map 
var map; 

// markers for map 
var markers = []; 

// info window 
var info = new google.maps.InfoWindow(); 

// execute when the DOM is fully loaded 
$(function() { 

    // styles for map 
    // https://developers.google.com/maps/documentation/javascript/styling 
    var styles = [ 

     // hide Google's labels 
     { 
      featureType: "all", 
      elementType: "labels", 
      stylers: [ 
       {visibility: "off"} 
      ] 
     }, 

     // hide roads 
     { 
      featureType: "road", 
      elementType: "geometry", 
      stylers: [ 
       {visibility: "off"} 
      ] 
     } 

    ]; 

    // options for map 
    // https://developers.google.com/maps/documentation/javascript/reference#MapOptions 
    var options = { 
     center: {lat: 42.3770, lng: -71.1256}, // Cambridge, MA 
     disableDefaultUI: true, 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     maxZoom: 14, 
     panControl: true, 
     styles: styles, 
     zoom: 13, 
     zoomControl: true 
    }; 

    // get DOM node in which map will be instantiated 
    var canvas = $("#map-canvas").get(0); 

    // instantiate map 
    map = new google.maps.Map(canvas, options); 

    // configure UI once Google Map is idle (i.e., loaded) 
    google.maps.event.addListenerOnce(map, "idle", configure); 

}); 

/** 
* Adds marker for place to map. 
*/ 
function addMarker(place) 
{ 
    // initialize marker 
    var marker = new google.maps.Marker({ 
     position: {lat: place.latitude, lng: place.longitude}, 
     map: map, 
     title: place.place_name + ', ' + place.admin_name1, 
     icon: "http://maps.google.com/mapfiles/kml/pal2/icon31.png" 
    }); 

    // add marker with its place to markers array 
    markers.push({marker, place}); 

    index = markers.length - 1 

    // add event listener to the marker 
    google.maps.event.addListener(markers[index].marker, 'click', showArticles(markers[index])) 
} 

/** 
* Gets the articles to be displayed 
*/ 
function showArticles(local) 
{ 
    var parameters = { 
     geo: local.place.place_name 
    }; 

    // get articles for the place 
    json = $.getJSON(Flask.url_for("articles"), parameters); 

    // store those articles in a string containing html 
    html = "<ul>" 

    json.done(function(){ 

     if(json.responseJSON){ 
      for (var i = 0; i < json.responseJSON.length; i++){ 
      html += "<li><a src=\"" + json.responseJSON[i].link + "\">" + json.responseJSON[i].title + "</a></li>"; 
      } 

      html += "</ul>" 

      console.log(json.responseJSON) 
      console.log(html) 

      showInfo(local.marker, html) 

     }}).fail(function(){ 
      showInfo(local.marker, "") 
     }) 

} 

/** 
* Configures application. 
*/ 
function configure() 
{ 
    // update UI after map has been dragged 
    google.maps.event.addListener(map, "dragend", function() { 

     // if info window isn't open 
     // http://stackoverflow.com/a/12410385 
     if (!info.getMap || !info.getMap()) 
     { 
      update(); 
     } 
    }); 

    // update UI after zoom level changes 
    google.maps.event.addListener(map, "zoom_changed", function() { 
     update(); 
    }); 

    // configure typeahead 
    $("#q").typeahead({ 
     highlight: false, 
     minLength: 1 
    }, 
    { 
     display: function(suggestion) { return null; }, 
     limit: 10, 
     source: search, 
     templates: { 
      suggestion: Handlebars.compile(
       "<div>" + 
       "{{place_name}}, {{admin_name1}}, {{postal_code}}" + 
       "</div>" 
      ) 
     } 
    }); 

    // re-center map after place is selected from drop-down 
    $("#q").on("typeahead:selected", function(eventObject, suggestion, name) { 

     // set map's center 
     map.setCenter({lat: parseFloat(suggestion.latitude), lng: parseFloat(suggestion.longitude)}); 

     // update UI 
     update(); 
    }); 

    // hide info window when text box has focus 
    $("#q").focus(function(eventData) { 
     info.close(); 
    }); 

    // re-enable ctrl- and right-clicking (and thus Inspect Element) on Google Map 
    // https://chrome.google.com/webstore/detail/allow-right-click/hompjdfbfmmmgflfjdlnkohcplmboaeo?hl=en 
    document.addEventListener("contextmenu", function(event) { 
     event.returnValue = true; 
     event.stopPropagation && event.stopPropagation(); 
     event.cancelBubble && event.cancelBubble(); 
    }, true); 

    // update UI 
    update(); 

    // give focus to text box 
    $("#q").focus(); 
} 

/** 
* Removes markers from map. 
*/ 
function removeMarkers() 
{ 
    for(var i = 0; i < markers.length; i++){ 
     markers[i].marker.setMap(null) 
    } 

    markers = [] 
} 

/** 
* Searches database for typeahead's suggestions. 
*/ 
function search(query, syncResults, asyncResults) 
{ 
    // get places matching query (asynchronously) 
    var parameters = { 
     q: query 
    }; 
    $.getJSON(Flask.url_for("search"), parameters) 
    .done(function(data, textStatus, jqXHR) { 

     // call typeahead's callback with search results (i.e., places) 
     asyncResults(data); 
    }) 
    .fail(function(jqXHR, textStatus, errorThrown) { 

     // log error to browser's console 
     console.log(errorThrown.toString()); 

     // call typeahead's callback with no results 
     asyncResults([]); 
    }); 
} 

/** 
* Shows info window at marker with content. 
*/ 
function showInfo(marker, content) 
{ 
    // start div 
    var div = "<div id='info'>"; 
    if (typeof(content) == "undefined") 
    { 
     // http://www.ajaxload.info/ 
     div += "<img alt='loading' src='/static/ajax-loader.gif'/>"; 
    } 
    else 
    { 
     div += content 
    } 

    // end div 
    div += "</div>"; 

    // set info window's content 
    info.setContent(div); 

    // open info window (if not already open) 
    info.open(map, marker); 
} 

/** 
* Updates UI's markers. 
*/ 
function update() 
{ 
    // get map's bounds 
    var bounds = map.getBounds(); 
    var ne = bounds.getNorthEast(); 
    var sw = bounds.getSouthWest(); 

    // get places within bounds (asynchronously) 
    var parameters = { 
     ne: ne.lat() + "," + ne.lng(), 
     q: $("#q").val(), 
     sw: sw.lat() + "," + sw.lng() 
    }; 
    $.getJSON(Flask.url_for("update"), parameters) 
    .done(function(data, textStatus, jqXHR) { 

     // remove old markers from map 
     removeMarkers(); 

     // add new markers to map 
     for (var i = 0; i < data.length; i++) 
     { 
      addMarker(data[i]); 
     } 
    }) 
    .fail(function(jqXHR, textStatus, errorThrown) { 

     // log error to browser's console 
     console.log(errorThrown.toString()); 
    }); 

}; 

的Python:

import os 
import re 
from flask import Flask, jsonify, render_template, request, url_for 
from flask_jsglue import JSGlue 

from cs50 import SQL 
from helpers import lookup 

# configure application 
app = Flask(__name__) 
JSGlue(app) 

# ensure responses aren't cached 
if app.config["DEBUG"]: 
    @app.after_request 
    def after_request(response): 
     response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" 
     response.headers["Expires"] = 0 
     response.headers["Pragma"] = "no-cache" 
     return response 

# configure CS50 Library to use SQLite database 
db = SQL("sqlite:///mashup.db") 

@app.route("/") 
def index(): 
    """Render map.""" 
    if not os.environ.get("API_KEY"): 
     raise RuntimeError("API_KEY not set") 
    return render_template("index.html", key=os.environ.get("API_KEY")) 

@app.route("/articles") 
def articles(): 
    """Look up articles for geo.""" 

    # get geo 
    geo = request.args.get("geo") 

    # if there is no geo, return error 
    if geo == '' or geo == None: 
     raise RuntimeError("missing geo") 

    # get articles for this geo 
    articles = lookup(geo) 

    if len(articles) > 5: 
     articles = articles[:5] 

    # return them as a json object 
    return jsonify(articles) 

@app.route("/search") 
def search(): 
    """Search for places that match query.""" 

    place = request.args.get("q") + "%" 

    # get everything that mathes this query 
    places = db.execute("SELECT * FROM places WHERE postal_code LIKE :place OR place_name LIKE :place OR admin_name1 LIKE :place LIMIT 10", place=place) 

    # return them as objects 
    return jsonify(places) 

@app.route("/update") 
def update(): 
    """Find up to 10 places within view.""" 

    # ensure parameters are present 
    if not request.args.get("sw"): 
     raise RuntimeError("missing sw") 
    if not request.args.get("ne"): 
     raise RuntimeError("missing ne") 

    # ensure parameters are in lat,lng format 
    if not re.search("^-?\d+(?:\.\d+)?,-?\d+(?:\.\d+)?$", request.args.get("sw")): 
     raise RuntimeError("invalid sw") 
    if not re.search("^-?\d+(?:\.\d+)?,-?\d+(?:\.\d+)?$", request.args.get("ne")): 
     raise RuntimeError("invalid ne") 

    # explode southwest corner into two variables 
    (sw_lat, sw_lng) = [float(s) for s in request.args.get("sw").split(",")] 

    # explode northeast corner into two variables 
    (ne_lat, ne_lng) = [float(s) for s in request.args.get("ne").split(",")] 

    # find 10 cities within view, pseudorandomly chosen if more within view 
    if (sw_lng <= ne_lng): 

     # doesn't cross the antimeridian 
     rows = db.execute("""SELECT * FROM places 
      WHERE :sw_lat <= latitude AND latitude <= :ne_lat AND (:sw_lng <= longitude AND longitude <= :ne_lng) 
      GROUP BY country_code, place_name, admin_code1 
      ORDER BY RANDOM() 
      LIMIT 10""", 
      sw_lat=sw_lat, ne_lat=ne_lat, sw_lng=sw_lng, ne_lng=ne_lng) 

    else: 

     # crosses the antimeridian 
     rows = db.execute("""SELECT * FROM places 
      WHERE :sw_lat <= latitude AND latitude <= :ne_lat AND (:sw_lng <= longitude OR longitude <= :ne_lng) 
      GROUP BY country_code, place_name, admin_code1 
      ORDER BY RANDOM() 
      LIMIT 10""", 
      sw_lat=sw_lat, ne_lat=ne_lat, sw_lng=sw_lng, ne_lng=ne_lng) 

    # output places as JSON 
    return jsonify(rows) 

這是當我跑步時的頁面在控制檯上出現的錯誤,如果需要的話,我可以留下一個鏈接到服務器應用程序正在運行的位置。 enter image description here

+0

錯誤的圖片信息和代碼不是非常有用。請在您的問題中提供錯誤的完整文本(並可能對標題有幫助),以及產生該錯誤的[mcve]。 – geocodezip

+0

對不起,這是唯一出現的錯誤,而且,如果我嘗試從代碼中刪除任何內容,我會以某種方式破壞應用程序。這是應用程序的鏈接,它現在正在運行,也許你可以在控制檯https://ide50-lucalopes.cs50.io中找到一些東西,再次,我對編程非常陌生,一直只是爲了在一個多月的時間裏,網絡編程只需一週時間,對不起,我無法提供更多信息。 – LucaLopes

+0

@geocodezip只要問我一些更具體的問題,我會很樂意提供給你。 – LucaLopes

回答

0

下面的代碼是在第93行返回一個未定義的值:當您嘗試訪問json.responseJSON第100行發生

// get articles for the place 
json = $.getJSON(Flask.url_for("articles"), parameters); 

錯誤。您使用需要的條件語句被什麼東西更像是下列之一:

if (typeof json != "undefined") 

if (json.responseJSON.length > 0) 
+0

我只嘗試用返回的值做一些事情,如果有值的話,有一個if條件來檢查它。此外,這部分代碼應該爲特定地點獲取文章,並且我會收到這些文章。 – LucaLopes

+0

在第100行,檢查json var是否未定義:if(typeof json!=「undefined」) – Dedering

+0

剛剛嘗試過,沒有更改任何內容,之前我有一個json.responseJSON錯誤,因爲它是未定義的,我補充說,它解決了這個問題,這是另一件事 – LucaLopes