【问题标题】:Mapbox GL Popup set content with custom tagMapbox GL Popup 使用自定义标签设置内容
【发布时间】:2018-06-22 02:52:04
【问题描述】:

我正在尝试创建一个点击弹出窗口的标记,到目前为止一切顺利, 问题是当我尝试将弹出窗口的内容设置为我的自定义标签时,例如

let popup = new mapboxgl.Popup()
    .setHTML("<custom-tag></custom-tag>") 

我知道 setDOMContent 的选项,但我没能把它弄好......它应该与 document.createElement('custom-tag') 一起使用em> 所以如果你能帮助我了解如何将它与自定义组件一起使用。 谢谢你的帮助!

【问题讨论】:

  • 组件“”从何而来?从角度?如果它是真的,我认为 Angular 不会在运行时解析你的 DOM,编译并包含你的组件
  • “编译并包含你的组件”是什么意思? 'custom-tag' 是我创建的带有 ts 和 html 的组件
  • Angular 不知道你动态添加了标签。所以他不知道他需要重新渲染你的组件。
  • 我如何告诉 Angular 包含我的组件?

标签: javascript jquery angular mapbox mapbox-gl-js


【解决方案1】:

我能够使用 Angular ComponentFactoryResolver 让它工作。有一些设置,但是一旦你让它工作,你可以用它来渲染你想要的任何组件(并将它放在你想要的任何地方......包括一个地图框弹出窗口)。

我不确定这是否仍然是执行此操作的“正确”方式(我仍在使用 Angular v5),但它确实有效。

1) 创建动态组件服务(不记得我是从哪里得到这个的……对不起,不管你是谁)

import { Injectable, Injector, ApplicationRef, ComponentFactoryResolver, ComponentRef, Type } from '@angular/core'

@Injectable()
export class DynamicComponentService {

    private compRef: ComponentRef<any>;

    constructor(private injector: Injector,
                private resolver: ComponentFactoryResolver,
                private appRef: ApplicationRef) { }


    public injectComponent<T>(component: Type<T>, propertySetter?: (type: T) => void): HTMLDivElement {
        // Remove the Component if it Already Exists
        if (this.compRef) this.compRef.destroy();

        // Resolve the Component and Create
        const compFactory = this.resolver.resolveComponentFactory(component);
        this.compRef = compFactory.create(this.injector);

        // Allow a Property Setter to be Passed in (To Set a Model Property, etc)
        if (propertySetter)
            propertySetter(this.compRef.instance);

        // Attach to Application
        this.appRef.attachView(this.compRef.hostView);

        // Create Wrapper Div and Inject Html
        let div = document.createElement('div');
        div.appendChild(this.compRef.location.nativeElement);

        // Return the Rendered DOM Element
        return div;
    }
}

2) 使用该服务在 mapbox-gl 弹出窗口中呈现您的自定义组件

import { MyCustomMapboxPopup } from "../app/components/my-custom-mapbox-popup.component"
import { DynamicComponentService } from "../services/dynamic-component";

...
// Inside a map.on("click") or wherever you want to create your popup

// Inject Component and Render Down to HTMLDivElement Object
let popupContent = this.dynamicComponentService.injectComponent(
                MyCustomMapboxPopup,
                x => x.model = new PopupModel()); // This Is where You can pass
// a Model or other Properties to your Component

 new mapboxgl.Popup({ closeOnClick: false })
     .setLngLat(...wherever you want the popup to show) 
     .setDOMContent(popupContent)
     .addTo(map);
...

为了避免混淆,自定义弹出组件可能如下所示:

import { Component } from '@angular/core';

@Component({
    selector: "custom-mapbox-popup",
    templateUrl: "./my-custom-mapbox-popup.component.html"
})
export class MyCustomMapboxPopup {
    public model: PopupModel; // Model Property
}

// HTML
<div class="my-custom-popup">
    <div *ngIf="model">
        <h3>{{this.model.SomeModelProperty}}</h3>
    </div>
</div>

【讨论】:

  • 非常感谢,这是一个很好的解决方案,但我有一个问题?我如何将数据传递给子组件?
  • @Osamakhodrog,注释了您可以在哪里传递数据:x =&gt; x.model = new PopupModel()); // This Is where You can pass // a Model or other Properties to your Component
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
相关资源
最近更新 更多