首页 > 解决方案 > 使用 Google Places API 和 KnockoutJS 列出地名

问题描述

我想检索 Google Places API 搜索返回的名称并使用 KnockoutJS 列出它们。

我想使用 Google Places API 搜索地点。我想在地图上标记这些地方,并使用 KnockoutJS 在无序列表中列出它们的名称。我能够将这些标记放在地图上,但无法使用 KnockoutJS 在无序列表中列出它们的名称。这是我的代码。

HTML:

<h4>Search Results<h4>
    <ul class="binding" data-bind="foreach: placesArray">
        <li class="binding" data-bind="text: $data">
            <span class="binding" data-bind="text: $index"></span>
        </li>
</ul>

JavaScript:

我发现极其困难的是我无法存储placesArray = getNames(results)在全局变量placesArray中。我认为如果我在本地添加 knockoutJS 可能会起作用,但ko.applyBindings如果我第二次搜索会导致错误。

let placesArray;
function searchPlaces() {
    let bounds = map.getBounds();
    hideMarkers(placeMarkers);
    let placesService = new google.maps.places.PlacesService(map);
    let placeName = placeInput.value;
    placesService.textSearch({
        query: placeName, // placeName is a string like "restaurants"
        bounds: bounds
    }, function(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            createMarkers(results);
            placesArray = getNames(results);
            // placesArray is an array of strings like ["McDonalds", "KFC", "Wendy's",...], I want to list them in <li> //
        }
    });
}

function getNames(placesArray) {
    let placeNamesArray = [];
    for (let i=0; i < placesArray.length; i++) {
        let name = placesArray[i].name;
        placeNamesArray.push(name);
    }
    return placeNamesArray;
}

如果我在本地引入了 KnockoutJS,则名称会正确列出,但如果我第二次运行此函数,则仅列出一次。ko.applyBindings将引发错误,因为我多次将绑定应用于相同的元素。

function searchPlaces() {
    let bounds = map.getBounds();
    hideMarkers(placeMarkers);
    let placesService = new google.maps.places.PlacesService(map);
    let placeName = placeInput.value;
    placesService.textSearch({
        query: placeName,
        bounds: bounds
    }, function(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            createMarkers(results);
            let placesArray = getNames(results);
            let SimpleListModel = function() {
                this.placesArray = ko.observableArray(placesArray);
            }
            ko.applyBindings(new SimpleListModel());
        }
    });
}

标签: javascriptknockout.js

解决方案


viewmodel 和 Knockout observable 的想法是,您可以在获得任何新信息时对其进行更新,并将其反映在 HTML 中。因此,您最初可以创建一个空的 observable,然后用您搜索的值填充它。

let SimpleListModel = function() {
    this.placesArray = ko.observableArray();
}
let modelInstance = new SimpleListModel();
ko.applyBindings(modelInstance);

function searchPlaces() {
    let bounds = map.getBounds();
    hideMarkers(placeMarkers);
    let placesService = new google.maps.places.PlacesService(map);
    let placeName = placeInput.value;
    placesService.textSearch({
        query: placeName,
        bounds: bounds
    }, function(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            createMarkers(results);
            let placesArray = getNames(results);
            modelInstance.placesArray(placesArray);
        }
    });
}

推荐阅读