属性绑定映射单击事件,在ngx-leaflet / Angular 2中使用下拉选择输入

时间:2018-06-05 14:23:41

标签: angular typescript leaflet property-binding ngx-leaflet

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

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

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

clicked最初在app组件中定义为空字符串。单击多边形时,我将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);
    });
  }
}

1 个答案:

答案 0 :(得分:1)

可能会在Angular区域外调用onEachFeature函数和layer.on('click'...事件回调。如果是这种情况,则更改检测将不会自动起作用。您应该在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实例注入您的组件。