【问题标题】:angular component into leaflet popup角度分量进入传单弹出窗口
【发布时间】:2017-07-09 11:12:30
【问题描述】:

无法弄清楚如何将组件生成到传单弹出窗口中。 我尝试了两件事:

首先,将组件选择器集成到html中,但是看起来好像angular没有编译它:

    let my geojson = L.geoJSON(data, {
        onEachFeature: (feature, layer) => {
            let popup = L.popup().setContent('<app-component-detail></app-component-detail>');
            layer.on({
                click: () => {
                    layer.bindPopup(popup);
                }
            })
        }
    }).addTo(map);

当我点击地图上的一个点时,弹出窗口是空的。

然后我考虑使用“resolveComponentFactory”将组件生成到 ViewContainerRef 中。如果我用@ViewChild 调用我的视图元素,效果很好:

模板:

<div #myContainer></div>

逻辑:

@ViewChild('myContainer', { read: ViewContainerRef } ) myContainer: ViewContainerRef;
private generatedComponent= this.componentFactoryResolver.resolveComponentFactory(componentDetail);
let my geojson = L.geoJSON(data, {
    onEachFeature: (feature, layer) => {
        layer.on({
            click: () => {
                this.myContainer.createComponent(this.generatedComponent);
            }
        })
    }
}).addTo(map);

现在我想将我的组件直接生成到弹出窗口中。我想我需要在弹出窗口的内容中设置一个 ViewContainerRef。类似的东西:

@ViewChild('popup', { read: ViewContainerRef } ) popup: ViewContainerRef;
private generatedComponent= this.componentFactoryResolver.resolveComponentFactory(componentDetail);
let my geojson = L.geoJSON(data, {
    onEachFeature: (feature, layer) => {
        let popup = L.popup().setContent('<div #popup></div>');
        layer.on({
            click: () => {
                layer.bindPopup(popup);
                this.popup.createComponent(this.generatedComponent);
            }
        })
    }
}).addTo(map);

编辑:这是我将这个solution 转换为leaflet.js 的方法

    let geojson = L.geoJSON(data, {
  style: () => defaultStyle,
  onEachFeature: (feature, layer) => {
    let popup = L.popup();
    layer.on({
      click: () => {
        this.zone.run( () => {

          if(this.componentRef){
            this.componentRef.destroy();
          }
          const compFactory = this.componentFactoryResolver.resolveComponentFactory(componentDetailmponent);
          this.componentRef = compFactory.create(this.injector);

          if (this.appRef['attachView']) { // since 2.3.0
           this.appRef['attachView'](this.componentRef.hostView);
           this.componentRef .onDestroy(() => {
             this.appRef['detachView'](this.componentRef.hostView);
          });
         } else {
          this.appRef['registerChangeDetector'](this.componentRef.changeDetectorRef);
          this.componentRef.onDestroy(() => {
            this.appRef['unregisterChangeDetector'](this.componentRef.changeDetectorRef);
          });
          }

          let div = document.createElement('div');
          div.appendChild(this.componentRef.location.nativeElement);
          popup.setContent(div);
        }
      )

      }
    });
    layer.bindPopup(popup);
  }
});

【问题讨论】:

  • 感谢您的链接。我试图将其转置为传单,请参阅编辑帖子
  • 你有对应的plunker吗?
  • 你忘了this.appRef.attachView(this.compRef.hostView);吗?这很关键
  • 我做到了……现在可以了!非常感谢@yurzui。

标签: angular leaflet


【解决方案1】:

这是一个可行的解决方案:

创建组件

component = this.resolver.resolveComponentFactory(PopupComponent).create(this.injector);

使用 NG 组件作为 HTML:

component.location.nativeElement

例如:

this.bindPopup(this.component.location.nativeElement);

地点:

  • 解析器:ComponentFactoryResolver -> 来自“@angular/core”;
  • 注射器:注射器 -> 来自“@angular/core”;

记得添加'app.module.ts':

entryComponents: [PopupComponent]

额外

  • Angular 必须收到关于“更改”的通知,调用:

    component.changeDetectorRef.detectChanges()

  • 如果您想在弹出窗口中使用输入字段:

    DomEvent.disableClickPropagation(this.component.location.nativeElement);

:)

【讨论】:

  • 如何将@Inputs 作为参数传递?
【解决方案2】:

@miguel-de-matos

 const component = this.resolver.resolveComponentFactory(MyComponent).create(this.injector);
 component.instance.title = 'Super Title';
 component.changeDetectorRef.detectChanges();

【讨论】:

    【解决方案3】:

    这是我将这个solution 转换为leaflet.js 的方法:

    let geojson = L.geoJSON(data, {
     onEachFeature: (feature, layer) => {
      let popup = L.popup();
      layer.on({
        click: () => {
          this.zone.run( () => {
    
          if(this.componentRef){
            this.componentRef.destroy();
          }
          const compFactory = this.componentFactoryResolver.resolveComponentFactory(componentDetailmponent);
          this.componentRef = compFactory.create(this.injector);
    
          if (this.appRef['attachView']) { // since 2.3.0
           this.appRef['attachView'](this.componentRef.hostView);
           this.componentRef .onDestroy(() => {
             this.appRef['detachView'](this.componentRef.hostView);
          });
         } else {
          this.appRef['registerChangeDetector'](this.componentRef.changeDetectorRef);
          this.componentRef.onDestroy(() => {
            this.appRef['unregisterChangeDetector'](this.componentRef.changeDetectorRef);
          });
          }
    
          let div = document.createElement('div');
          div.appendChild(this.componentRef.location.nativeElement);
          popup.setContent(div);
        }
      )
    
      }
    });
    layer.bindPopup(popup);
    }
    });
    

    【讨论】:

      猜你喜欢
      • 2017-03-30
      • 2017-12-22
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      相关资源
      最近更新 更多