简体   繁体   English

如何在javascript侦听器中删除重复的函数?

[英]How to remove duplicated function in javascript listener?

Objective 目的

I wish to remove the duplication code brought by the anonymous function calls. 我希望删除匿名函数调用带来的重复代码。

Background 背景

I am doing a very simple project where I use Google Maps API to show a map with two searchboxes. 我正在做一个非常简单的项目,我在其中使用Google Maps API来显示带有两个搜索框的地图。 The user puts a start address and an end address in those boxes and I show markers in the map. 用户在这些框中输入开始地址和结束地址,然后在地图上显示标记。

To achieve this I have two anonymous functions for the listeners, which are exactly equal except for one point - one uses the startSearchBox and the other one the endSearchBox . 为了实现这一点,我为侦听器提供了两个匿名函数,除了一个要点外,其他函数完全相同-一个使用startSearchBox ,另一个使用endSearchBox

What I tried 我尝试了什么

This duplication of code is unnecessary, and so I tried to pass the searchboxes as a parameter to the anonymous function, however that didn't work. 代码的重复是不必要的,因此我尝试将搜索框作为参数传递给匿名函数,但是没有用。

I also considered creating the searchboxes as global variables, but that is a bad practice I wish to avoid. 我还考虑过将搜索框创建为全局变量,但这是我想避免的不良做法。

How can I eliminate the duplication in this code? 如何消除此代码中的重复项?

Code

function initSearchBoxes() {
    // Create the search box and link it to the UI element.
    let startInput = document.getElementById('start-input');
    let startSearchBox = new google.maps.places.SearchBox(startInput);

    let endInput = document.getElementById('end-input');
    let endSearchBox = new google.maps.places.SearchBox(endInput);

    // Bias the SearchBox results towards current map's viewport.
    map.addListener('bounds_changed', function() {
        startSearchBox.setBounds(map.getBounds());
        endSearchBox.setBounds(map.getBounds());
    });

    startSearchBox.addListener('places_changed', function() {

        deleteAllMarkers();

        let places = startSearchBox.getPlaces();
        if (places.length == 0) {
            return;
        }

        // For each place, get the icon, name and location.
        let bounds = new google.maps.LatLngBounds();
        places.forEach(function(place) {

            // // Create a marker for each place.
            let newMarker = createMarker(place.geometry.location, place.name, markerLabels.nextSymbol(), true);
            markerLib.trackMarker(newMarker);

            newMarker.setMap(map);

            if (place.geometry.viewport) {
                // Only geocodes have viewport.
                bounds.union(place.geometry.viewport);
            }
            else {
                bounds.extend(place.geometry.location);
            }
        });
        map.fitBounds(bounds);
    });

    endSearchBox.addListener('places_changed', function() {

        deleteAllMarkers();

        let places = endSearchBox.getPlaces();
        if (places.length == 0) {
            return;
        }

        // For each place, get the icon, name and location.
        let bounds = new google.maps.LatLngBounds();
        places.forEach(function(place) {

            // // Create a marker for each place.
            let newMarker = createMarker(place.geometry.location, place.name, markerLabels.nextSymbol(), true);
            markerLib.trackMarker(newMarker);

            newMarker.setMap(map);

            if (place.geometry.viewport) {
                // Only geocodes have viewport.
                bounds.union(place.geometry.viewport);
            }
            else {
                bounds.extend(place.geometry.location);
            }
        });
        map.fitBounds(bounds);
    });
}

You can wrap your callback function in another "factory" function. 您可以将回调函数包装在另一个“工厂”函数中。 The factory will take a parameter (the search box reference) and then it will return the actual handler: 工厂将获取一个参数(搜索框引用),然后将返回实际的处理程序:

function makeSearchHandler(searchBox) {
    return function() {

        deleteAllMarkers();

        let places = searchBox.getPlaces();
        if (places.length == 0) {
            return;
        }

        // For each place, get the icon, name and location.
        let bounds = new google.maps.LatLngBounds();
        places.forEach(function(place) {

            // // Create a marker for each place.
            let newMarker = createMarker(place.geometry.location, place.name, markerLabels.nextSymbol(), true);
            markerLib.trackMarker(newMarker);

            newMarker.setMap(map);

            if (place.geometry.viewport) {
                // Only geocodes have viewport.
                bounds.union(place.geometry.viewport);
            }
            else {
                bounds.extend(place.geometry.location);
            }
        });
        map.fitBounds(bounds);
    };
}

That function contains the code from your original, but instead of directly referring to either startSearchBox or endSearchBox , it uses the parameter passed to the factory. 该函数包含原始代码,但不是直接引用startSearchBoxendSearchBox ,而是使用传递给工厂的参数。 The returned function will therefore work like yours, but the code is only present once. 因此,返回的函数将像您一样工作,但是该代码仅出现一次。

You can then use that function to create the callbacks: 然后,您可以使用该函数创建回调:

startSearchBox.addListener('places_changed', makeSearchHandler(startSearchBox));
endSearchBox.addListener('places_changed', makeSearchHandler(endSearchBox));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM