传单弹出循环

Leaflet Popup Loop

本文关键字:循环 单弹出      更新时间:2023-09-26

我最近一直在玩Leaflet,并将其集成到WordPress自定义帖子类型中。我在城市的自定义帖子类型中添加了一个字段。然后它被编码为JavaScript并发送到Mapbox以获取坐标。然后将坐标发送到显示标记的函数。这部分效果很好。我遇到的问题是让标题正确循环并显示在弹出对话框中。当我查看源代码时,我看到名称和城市都正确编码。代码如下。谢谢!

          // Loops through CPT and puts both city and name into array
          // TODO: Rename hometown to something more relevant
          while ($loop->have_posts()) : $loop->the_post();
            $post_meta = get_post_meta($post->ID, 'hometown', true);
            $title = get_the_title($post->ID);
            if ( !empty ( $post_meta ) || !empty ( $title ) ) {
            $hometown[] = array(
                'city' => $post_meta,
                'name' => $title
            );
        }
        endwhile;
    <script>
    var hometown = <?php echo wp_json_encode($hometown); ?>;
    var map = L.map('map').setView([40, 0], 2);
    L.mapbox.accessToken = 'myToken';
    var geocoder = L.mapbox.geocoder('mapbox.places');
    for ( var i = 0; i < hometown.length; i++ )
    {
      geocoder.query(hometown[i].city, showLoc);
    }
   L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=myToken', {
   maxZoom: 18,
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
    '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
    'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
function showLoc(err, data) {
L.marker([data.latlng[0], data.latlng[1]], 2)
    .bindPopup(hometown[0].name)
    .addTo ( map );
}
 </script>

例如,我们有以下数组:

var homes = [{
    name: 'Jane Doe',
    city: 'Denver, Colorado'
},{
    name: 'John Doe',
    city: 'Houston, Texas'
}];

我们将遍历数组的项目,并从 Mapbox 的地理编码器服务查询每个城市属性:

for (var i = 0; i < homes.length; i++) {
    geocoder.query(homes[i].city, callback);
}

这实际上将按此顺序执行以下命令:

geocoder.query('Denver, Colorado', callback);
geocoder.query('Houston, Texas', callback);

完成这些请求后,它将为每个查询执行 callback 方法:

function callback (err, data) {
    // do stuff
}

问题是请求是异步的,我们无法确定它们将按照我们请求它们的相同顺序完成。因此,在callback方法中,我们无法直接知道结果来自哪个项目:

function callback (err, data) {
    // Who's data is this?
}

幸运的是,callback 方法提供的 data 对象在 data.results.query 属性中保存原始查询:

function callback (err, data) {
    console.log(data.results.query);
}

这会将['denver', 'colorado']['houston', 'texas']登录到您的控制台,具体取决于它来自哪个查询。现在,您可以在homes数组中搜索城市并返回名称:

function callback (err, data) {
    // join the query array so we get the same string as we've queried
    var city = data.results.query.join(', ');
    // iterate over the homes array
    for (var i = 0; i < homes.length; i++) {
        // compare cities in lowercase (result returns in lowercase)
        if (homes[i].city.toLowerCase() === city) {
            // found match, do stuff
        }
    }
}

对于您的解决方案,它看起来像这样:

function callback (err, data) {
    var city = data.results.query.join(', ');
    for (var i = 0; i < homes.length; i++) {
        if (homes[i].city.toLowerCase() === city) {
             new L.Marker([data.latlng[0], data.latlng[1]])
                 .bindPopup(homes[i].name)
                 .addTo(map);
        }
    }
}

你可以在这里尝试一下:http://jsfiddle.net/73hg2L4y/(使用你自己的令牌(

希望有帮助,祝你好运!

注意:一旦您有两个名称位于同一城市,您就会遇到麻烦,因此最好确保所有地址都是唯一的。