ngx-leaflet/Angular 2中带有下拉选择框的属性绑定映射单击事件 [英] Property binding map click event with dropdown select input in ngx-leaflet/Angular 2

查看:93
本文介绍了ngx-leaflet/Angular 2中带有下拉选择框的属性绑定映射单击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张包含区域多边形的地图.在地图下方,我有一个下拉选择输入,可动态读取多边形名称作为选项.当用户单击地图上的区域多边形时,我希望下拉选择输入使用选定的多边形名称(在geojson文件中作为名称"字段存在)进行更新.

I have a map with regional polygons. Below the map, I have a dropdown select input that dynamically reads in the polygon names as options. When the user clicks the regional polygons on the map, I want the dropdown select input to update with the selected polygon name (which exists as the 'name' field in the geojson file).

我认为实现此目的的方法是在HTML模板文件中使用属性绑定.因此,在我的选择类中,我将value属性设置为值clicked,如下所示:

I figure that the way to achieve this is to use property binding in the HTML template file. So in my select class, I set the value property as the value clicked, like so:

<select class="form-control" id="selectRegion" [value]="clicked">

clicked最初在应用程序组件中定义为空字符串.单击多边形时,将clicked设置为onEachFeature click事件内的多边形名称字段.控制台日志显示clicked变量正在正确更新.但是,选择输入不会按预期的那样与单击事件一起更新.

clicked is initially defined as an empty string in the app component. When a polygon is clicked, I set clicked as the polygon name field inside the onEachFeature click event. The console log shows that the clicked variable is updating properly. However, the select input does NOT update with the click events as expected.

我怀疑问题是this在我的函数中没有正确更新?如何获取选择输入以更新地图点击事件?

I suspect that the issue is that this isn't properly updating inside my functions? How do I get the select input to update with my map click events?

这是一些代码(基于Asymmetrik的ngx-leaflet-tutorial-ngcli):

Here's some code (based on ngx-leaflet-tutorial-ngcli from Asymmetrik):

Geojson(在资产文件夹中另存为polygons.geojson:

Geojson (saved as polygons.geojson in the assets folder:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "stroke": "#555555",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#555555",
        "fill-opacity": 0.5,
        "name": "poly1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -121.95098876953125,
              46.82966386051541
            ],
            [
              -121.78482055664061,
              46.82966386051541
            ],
            [
              -121.78482055664061,
              46.91368905872705
            ],
            [
              -121.95098876953125,
              46.91368905872705
            ],
            [
              -121.95098876953125,
              46.82966386051541
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "stroke": "#555555",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#555555",
        "fill-opacity": 0.5,
        "name": "poly2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -121.77726745605469,
              46.83107318799318
            ],
            [
              -121.62963867187499,
              46.83107318799318
            ],
            [
              -121.62963867187499,
              46.913220009605624
            ],
            [
              -121.77726745605469,
              46.913220009605624
            ],
            [
              -121.77726745605469,
              46.83107318799318
            ]
          ]
        ]
      }
    }
  ]
}

App.module.ts:

App.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { LeafletModule } from '@asymmetrik/ngx-leaflet';
import { HttpClientModule } from '@angular/common/http';


import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    LeafletModule.forRoot(),
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

App.component.html:

App.component.html:

<div class="map"
  leaflet
  [leafletLayers]="layers"
     [leafletFitBounds]="fitBounds"></div>
<div class="form-group">
  <select class="form-control" id="selectRegion" [value] = "clicked">
    <option *ngFor="let region of regions">{{ region }}</option>
  </select>
</div>

App.component.ts:

App.component.ts:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import * as L from 'leaflet';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  layers: L.Layer[];
  fitBounds = [[46.67, -122.25], [47.01, -121.302]];
  regions = [];
  clicked = '';

  constructor(private http: HttpClient) { }

  ngOnInit() {

    // read in geojson of poly
    this.http.get<any>('/assets/polygons.geojson')
      .subscribe(poly => {

        const tileLayer = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png', {
          subdomains: 'abcd',
          maxZoom: 19
        });

        const polyLayer = L.geoJSON(poly, {
          onEachFeature: this.onEachFeature.bind(this)
        });

        this.layers = [ tileLayer, polyLayer ];
        console.log(this);
      });
  }

  // loop through each feature of polyLayer
  onEachFeature(feature, layer) {

    // push polygon names to regions array
    this.regions.push(feature.properties.name);

    layer.on('click', <LeafletMouseEvent> (e) => {
      this.clicked = e.target.feature.properties.name;
      console.log(this.clicked);
    });
  }
}

推荐答案

可能在Angular区域之外调用了onEachFeature函数和layer.on('click'...事件回调.在这种情况下,更改检测将不会自动进行.您应该将更改包装在zone.run()调用中,以确保在Angular区域中进行更改-如本例所示:

The onEachFeature function and layer.on('click'... event callback are likely being invoked outside of the Angular zone. If this is the case, then change detection won't automatically work. You should wrap the changes in zone.run() calls in order to ensure that your changes are being made in the Angular zone - as in this example:

// loop through each feature of polyLayer
onEachFeature(feature, layer) {

  this.zone.run(() => {
    // push polygon names to regions array
    this.regions.push(feature.properties.name);

    layer.on('click', <LeafletMouseEvent> (e) => {
      this.zone.run(() => {
        this.clicked = e.target.feature.properties.name;
        console.log(this.clicked);
      }
    });
  }

}

您可以按照以下说明进行操作( https://github .com/Asymmetrik/ngx-leaflet#a-note-about-change-detection ),以了解其工作原理并将ngZone实例注入到您的组件中.

You can follow these directions (https://github.com/Asymmetrik/ngx-leaflet#a-note-about-change-detection) to see how this works and to inject the ngZone instance into your component.

这篇关于ngx-leaflet/Angular 2中带有下拉选择框的属性绑定映射单击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆