0

我正在运行 Angular 6,我想动态地将一个图层添加到传单地图,但是如果图层是从另一个组件修改的,我无法检测到传单图层的变化。如果从执行图层更改,一切正常, map.component但如果我从外部进行更改,则一切正常:

例子:

map.component.ts

layers: Layer[];

addPolygon () {
    this.layers = [polygon([[ 43, 3 ], [ 42, 0 ], [ 44, 1 ]])]
}

map.component.html

<div class="map"
  leaflet
  (leafletMapReady)="onMapReady($event)"
  [leafletOptions]="options"
  [leafletLayers]="layers">
</div>
<div>
  <button type="button" name="button" (click)="addPolygon()"></button>
</div>

现在一切正常,只要单击按钮,多边形就会出现。但我需要该按钮位于另一个组件 ( form.component.ts) 中,因此我尝试与服务共享该addPolygon()功能:

服务器.service.ts

@Injectable()
export class ServerService {
  addPolygon: Function;
}

我修改MapComponent并添加了用于调用服务的构造函数

map.component.ts

export class MapComponent{
  layers: Layer[];

  constructor(private serverService: ServerService){ 
     this.serverService.addPolygon = this.addPolygon 
  };

form.component.ts

export class FormComponent implements OnInit {
  constructor(private serverService: ServerService) { }

  triggerMap() {
      this.serverService.addPolygon()
  }
}

但是,如果我绑定多边形中triggerMap()的按钮,form.component.html则不会将其添加到地图中。addPolygon然而,控制台说map.component.ts已经到达。

我什至尝试使用NgZone,但它没有任何区别。有什么建议吗?

角 CLI:6.0.8

4

1 回答 1

0

我想我弄清楚了你的具体问题。它并不是特定于 Angular 或 Leaflet。我认为它更像是 Typescript 和 Javascript 的产物(或者可能是特定于 AOT 编译和 TS->JS 转译工作方式的东西)。

基本上,我认为问题在于,当您将 addPolygon 函数分配给服务对象时,this上下文正在发生变化。因此,this最终成为服务this而不是组件this。结果是在我假设服务内部创建了一个新的图层数组。您可以(在某种程度上)通过在 MapComponent 中执行以下操作来确认这一点:

export class MapComponent {

  layers: Layer[] = [];
  counter = 0;

  constructor(
    private serverService: ServerService,
    private zone: NgZone
  ) {
    this.serverService.addPolygon = this.addPolygon;
  }

  options = {
      layers: [
          tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' })
      ],
      zoom: 5,
      center: latLng(42, 2)
  };


  addPolygon () {
    console.log('I am in addPolygon in MapComponent');
    this.counter++;
    console.log(`Here\'s the counter: ${this.counter}`);

    this.layers = [
        polygon( [[ 43, 3 ], [ 42, 0 ], [ 44, 1 ]] )
    ];
  }

  resetLayers () {
    console.log('Resetting layers');
    console.log(`Here\'s the counter: ${this.counter}`);
    this.layers = [];
  }

}

这里的想法是我正在修改counter内部的本地成员变量addPolygon,然后将其打印到控制台。我还将它打印到resetLayers函数内部的控制台。

当我按以下顺序单击按钮时:MapComponent、Reset、FormComponent,我得到以下输出:

I am in addPolygon in MapComponent
map.component.ts:36 Here's the counter: 1
map.component.ts:44 Resetting layers
map.component.ts:45 Here's the counter: 1
map.component.ts:34 I am in addPolygon in MapComponent
map.component.ts:36 Here's the counter: NaN

MapComponent click 将计数器从 0 增加到 1 并正确打印值为 1。Reset click 打印正确的计数器值 1。但是,FormComponent click 打印 NaN,因为它没有初始化为值,所以递增它会留下它作为 NaN。

为了确定哪个上下文用于 FormComponent 对 addPolygon 的调用,我为 AppComponent、ServerService 和 FormComponent 添加了初始化为不同值的计数器。事实证明,它addPolygon使用this来自ServerService.

因此,我认为您的问题的解决方案是将图层数组放在 ServerServicem 中,或者使用输出绑定将事件从 FormComponent 传递到作为 MapComponent 和 FormComponent 的父级的组件。

于 2018-07-26T23:34:34.607 回答