【问题标题】:Property binding map click event with dropdown select input in ngx-leaflet/Angular 2ngx-leaflet/Angular 2中带有下拉选择输入的属性绑定映射单击事件
【发布时间】:2018-06-05 14:23:41
【问题描述】:

我有一张带有区域多边形的地图。在地图下方,我有一个下拉选择输入,可以动态读取多边形名称作为选项。当用户单击地图上的区域多边形时,我希望下拉选择输入更新为所选多边形名称(在 geojson 文件中作为“名称”字段存在)。

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

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

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

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

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

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

{
  "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:

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:

<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:

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 typescript leaflet property-binding ngx-leaflet


    【解决方案1】:

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

    // 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 实例注入到您的组件中。

    【讨论】:

      猜你喜欢
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 2013-08-22
      • 2018-10-01
      • 2016-12-30
      • 1970-01-01
      相关资源
      最近更新 更多