Google地图位置自动填充 - 未捕获TypeError:无法读取属性' getPlace'未定义的

时间:2016-05-14 19:20:43

标签: angularjs google-maps maps google-places-api angular-google-maps

ScriptManager.RegisterStartupScript(updatePnl, updatePnl.GetType(), "Pop", "setTimeout(function() { openMsgModal5(); }, 200);", true);
setAutocomplete() {
    this.originPlaceId = null;
    this.destinationPlaceId = null;
    this.travelMode = google.maps.TravelMode.WALKING;
    this.directionsDisplay.setMap(this.map);

    this.setMapControls(this.map);

    this.setupClickListener('changemode-walking', google.maps.TravelMode.WALKING);
    this.setupClickListener('changemode-transit', google.maps.TravelMode.TRANSIT);
    this.setupClickListener('changemode-driving', google.maps.TravelMode.DRIVING);

    console.log(this.originInput);
    this.originAutocomplete = new google.maps.places.Autocomplete(this.originInput);
    this.originAutocomplete.bindTo('bounds', this.map);
    console.log(this.originAutocomplete);
    this.originAutocomplete.addListener('place_changed', function() {
        console.log(this.originAutocomplete);
        var place = this.originAutocomplete.getPlace();
        console.log("here", place);
        if (!place.geometry) {
            window.alert("Autocomplete's returned place contains no geometry");
            return;
        }
        this.expandViewportToFitPlace(this.map, place);

        // If the place has a geometry, store its place ID and route if we have
        // the other place ID
        this.originPlaceId = place.place_id;
        this.route(this.directionsService, this.directionsDisplay);
    });

    this.destinationAutocomplete = new google.maps.places.Autocomplete(this.destinationPlaceInput);
    this.destinationAutocomplete.bindTo('bounds',this.map);
    this.destinationAutocomplete.addListener('place_changed', function() {
        var place = this.destinationAutocomplete.getPlace();
        if (!place.geometry) {
            window.alert("Autocomplete's returned place contains no geometry");
            return;
        }
        this.expandViewportToFitPlace(this.map, place);

        // If the place has a geometry, store its place ID and route if we have
        // the other place ID
        this.destinationPlaceId = place.place_id;
        this.route(this.directionsService, this.directionsDisplay);
        //this.getNearbyPlaces(this.destinationPlaceId, 5000);
    });
};
setMapControls(map) {
    this.originInput = document.getElementById('origin-input');
    this.destinationPlaceInput = document.getElementById('destination-input');
    this.modes = document.getElementById('mode-selector');

    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.originInput);
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.destinationPlaceInput);
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.modes);
};

我有这些功能,它们应该从输入字段(originInput和destinationPlaceInput)向我提供来自Google Maps Places的路线A到B.

选择输入后,我在控制台中出现此错误:

  

未捕获的TypeError:无法读取属性' getPlace'未定义的

" place_changed"之后抛出此错误事件触发器。

2 个答案:

答案 0 :(得分:6)

place_changed - 回调中,关键字this指向已触发事件的对象。

所以你可以简单地使用

var place = this.getPlace();

而不是

var place = this.destinationAutocomplete.getPlace();

答案 1 :(得分:0)

如何保留控制器的上下文/ this

tldr:

创建一个返回带有上下文的函数的函数:

this.searchBox.addListener('places_changed', ((that) => () => this.placesChanged(that))(this));

说明

就像Dr.Molle指出的那样:this指向触发事件的对象,即要在其上添加事件侦听器的元素。

addListener采用函数声明。为了保持对控制器this的访问权限,您还可以创建一个闭包,将控制器的this传递给函数,如下所示:

this.searchBox.addListener('places_changed', ((that) => () => this.placesChanged(that))(this));

在这里,我定义了一个函数,该函数带有一个名为that的参数,执行后将返回一个包含this的函数。之所以闭包是因为内部函数的作用域保留了外部函数作用域(以及可能传递给that的其他变量)对this.placesChanged变量的引用。

现在,如果发出事件places_changed,则运行函数声明。我仍然可以在that函数内的this.placesChanged变量上更改属性。这是可能的,因为in对象是通过引用传递的(而原始类型是通过值传递的)。