Instantsearch v2 在视图和地图中的不同命中

Instantsearch v2 different hits in view and map

我们使用带有自定义地点小部件的即时搜索 (2.10.4) 来显示在地图上以及地图下方的结果。

地点小部件代码是这样的:

var placesWidget = {
    init: function(opts){

        var container = document.querySelector('#IS__radius');
        var radius = document.querySelector('#radiusSlider');

        var placesAutocomplete = places({
            container: container,
            templates: {
                value: function(suggestion) {
                    return suggestion.name;
                }
            }
        }).configure({
            type: 'city',
            aroundLatLngViaIP: false,
            useDeviceLocation: false,
        });;

        placesAutocomplete.on('change', function(e) {
            var location = e.suggestion;
            var lat = location.latlng['lat'];
            var lng = location.latlng['lng'];
            opts.helper.setQueryParameter('query', $('#IS__search').val());
            opts.helper.setQueryParameter('aroundLatLng', lat + ',' + lng);
            opts.helper.setQueryParameter('aroundRadius', parseInt($('#radiusSlider').val()));
            opts.helper.search();
        });

        container.addEventListener("input", onInputChange);
        function onInputChange(event) {
            if (event.currentTarget.value === "") {
                opts.helper.setQueryParameter("aroundLatLng");
                opts.helper.search();
            }
            if (event.currentTarget.value.length >= 2) {
                $('.searchbox__distri .rs__container').addClass('visible');
                $('.mapsContainer #hits').show();
            } else {
                $('.mapsContainer #hits').hide();
            }
        }

        $('button.ap-icon-clear').on('click', function(){
            $('.searchbox__distri .rs__container').removeClass('visible');
            $('.singleResult').slideUp(250).find('.viewer').html('');
            opts.helper.setQueryParameter("aroundLatLng");
            opts.helper.search();
        });

        enableRadiusSlider(opts);
    }
};

最初,所有标记以及地图下方的文本结果似乎都能正确显示。但是地图结果不正确地尊重地点搜索输入,正如您在这个屏幕截图中看到的那样:

下面的 6 个框是正确的,但地图显示的结果太多(但不是全部)。

我想,地图渲染中的线条(见下文)params.helper.setQueryParameter('query', $('#IS__search').val()); 应该可以解决这个问题。调试它给了我应该采用的正确值。

map = {
    _mapContainer: document.querySelector('#map-instantsearch-container'),
    markers: [],

    _hitToMarker: function(hit) {

        var icon = {
            url: 'typo3conf/ext/siteway/Resources/Public/Images/markerclusterer/basePin@2x.png',
            size: new google.maps.Size(39, 58),
            scaledSize: new google.maps.Size(39, 58)
        };

        var marker = new google.maps.Marker({
            position: {
                lat: hit._geoloc.lat,
                lng: hit._geoloc.lng
            },
            map: this._map,
            icon: icon,
            title: hit.company+' / '+hit.zip+' '+hit.city,
        });

        // trigger custom function on marker click
        window.google.maps.event.addListener(marker, 'click', function () {
            distriDetail(hit.objectID,this.position.lat(),this.position.lng());
        });

        return marker;
    },

    init: function(params) {

        radius = document.querySelector('#radius');

        this._helper = params.helper;

        // init the map
        this._map = new google.maps.Map(
            this._mapContainer,
            {
                zoom: 2,
                backgroundColor: "#eeeeee",
                styles: [{"elementType": "geometry","stylers": [{"color": "#f5f5f5"}]},{"elementType": "labels.icon","stylers": [{"visibility": "off"}]},{"elementType": "labels.text.fill","stylers": [{"color": "#616161"}]},{"elementType": "labels.text.stroke","stylers": [{"color": "#f5f5f5"}]},{"featureType": "administrative.land_parcel","elementType": "labels.text.fill","stylers": [{"color": "#bdbdbd"}]},{"featureType": "poi","elementType": "geometry","stylers": [{"color": "#eeeeee"}]},{"featureType": "poi","elementType": "labels.text.fill","stylers": [{"color": "#757575"}]},{"featureType": "poi.park","elementType": "geometry","stylers": [{"color": "#e5e5e5"}]},{"featureType": "poi.park","elementType": "labels.text.fill","stylers": [{"color": "#9e9e9e"}]},{"featureType": "road","elementType": "geometry","stylers": [{"color": "#ffffff"}]},{"featureType": "road.arterial","elementType": "labels.text.fill","stylers": [{"color": "#757575"}]},{"featureType": "road.highway","elementType": "geometry","stylers": [{"color": "#dadada"}]},{"featureType": "road.highway","elementType": "labels.text.fill","stylers": [{"color": "#616161"}]},{"featureType": "road.local","elementType": "labels.text.fill","stylers": [{"color": "#9e9e9e"}]},{"featureType": "transit.line","elementType": "geometry","stylers": [{"color": "#e5e5e5"}]},{"featureType": "transit.station","elementType": "geometry","stylers": [{"color": "#eeeeee"}]},{"featureType": "water","elementType": "geometry","stylers": [{"color": "#c9c9c9"}]},{"featureType": "water","elementType": "labels.text.fill","stylers": [{"color": "#9e9e9e"}]}],
                center: new google.maps.LatLng(51.0964656, 5.9588265),
            }
        );
    },

    render: function(params)
    {
        console.log('render fn');
        console.log(params);
        params.helper.setQueryParameter('query', $('#IS__search').val());

        // clear markers
        this.markers.forEach(function (marker) {
            marker.setMap(null);
        });

        // transform hits to Google Maps markers
        this.markers = params.results.hits.map(this._hitToMarker.bind(this));

        var bounds = new google.maps.LatLngBounds();

        // make sure we display the good part of the maps
        this.markers.forEach(function(marker) {
            bounds.extend(marker.getPosition());
        });

        var clusterStyles = [
            {
                textColor: 'white',
                textSize: 15,
                anchor: [12, 39],
                url: 'typo3conf/ext/siteway/Resources/Public/Images/markerclusterer/basePin.png',
                height: 70,
                width: 39
            },
            {
                textColor: 'white',
                textSize: 15,
                anchor: [12, 39],
                url: 'typo3conf/ext/siteway/Resources/Public/Images/markerclusterer/basePin.png',
                height: 70,
                width: 39
            },
            {
                textColor: 'white',
                textSize: 15,
                anchor: [12, 39],
                url: 'typo3conf/ext/siteway/Resources/Public/Images/markerclusterer/basePin.png',
                height: 70,
                width: 39
            }
        ];

        var mcOptions = {
            gridSize: 58,
            styles: clusterStyles,
            maxZoom: 15
        };

        var markerCluster = new MarkerClusterer(this._map, this.markers, mcOptions);

        this._map.fitBounds(bounds);

        // zoom on results
        var zoom = this._map.getZoom();
        this._map.setZoom(zoom > 14 ? 14 : zoom);
    }
};

为什么地图显示的结果与 hits 模板不同?没有意义。

问题似乎来自 MarkerClusterer。这是一个有状态的对象,因此它保留了地图上以前的标记。一种可能的解决方案是在 init 步骤创建集群。在 render 步骤中,您可以清除以前的标记并将新标记附加到集群上。 an example 展示了如何操作。