Mapbox GL Popup使用自定义标记设置内容 [英] Mapbox GL Popup set content with custom tag

查看:3587
本文介绍了Mapbox GL Popup使用自定义标记设置内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在点击时创建一个带弹出窗口的标记,到目前为止很好,
问题当我试图将弹出窗口的内容设置为我的自定义标记时,示例

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

我知道 setDOMContent 的选项但我没有设法做到正确...它假设使用 document.createElement('custom-tag'),所以如果你可以帮助我如何将它与自定义组件一起使用。
谢谢你的帮助!

解决方案

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



我不确定这是否仍然是正确的方式(我仍然在Angular v5上),但确实有效。



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



< pre class =lang-js prettyprint-override> 从'@ angular / core'导入{Injectable,Injector,ApplicationRef,ComponentFactoryResolver,ComponentRef,Type}

@Injectable( )
导出类DynamicComponentService {

private compRef:ComponentRef< any> ;;

构造函数(私有注入器:Injector,
私有解析器:ComponentFactoryResolver,
private appRef:ApplicationRef){}


public injectComponent< T>(组件:类型< T>,propertySetter?:(类型:T)=> void):HTMLDivElement {
//删除组件,如果它已经存在
if(this.compRef)this .compRef.destroy();

//解析组件并创建
const compFactory = this.resolver.resolveComponentFactory(component);
this.compRef = compFactory.create(this.injector);

//允许传入属性设置器(设置模型属性等)
if(propertySetter)
propertySetter(this.compRef.instance);

//附加到应用程序
this.appRef.attachView(this.compRef.hostView);

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

//返回渲染的DOM元素
返回div;
}
}

2)使用服务呈现自定义组件mapbox-gl popup

 从../app/components/my导入{MyCustomMapboxPopup}来自../services/dynamic-component的-custom-mapbox-popup.component
import {DynamicComponentService};

...
//在map.on(click)内或您想要创建弹出窗口的位置

//注入组件并向下渲染to HTMLDivElement Object
let popupContent = this.dynamicComponentService.injectComponent(
MyCustomMapboxPopup,
x => x.model = new PopupModel()); //这是你可以将
//模型或其他属性传递给组件的地方

new mapboxgl.Popup({closeOnClick:false})
.setLngLat(.. 。你想要弹出窗口显示的地方)
.setDOMContent(popupContent)
.addTo(map);
...

为了避免任何混淆,自定义弹出组件可能看起来像:

 从'@ angular / core'导入{Component}; 

@Component({
selector:custom-mapbox-popup,
templateUrl:./ my -custom-mapbox -popup.component.html
})
导出类MyCustomMapboxPopup {
public model:PopupModel; //模型属性
}

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


im trying to creater a marker with popup on click, so far so good, the problem is when im trying to set the content of the popup to be my custom tag, for example

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

I know about the option of setDOMContent but I didn't manage to get it right... it suppose to work with document.createElement('custom-tag') so if you can help me on how to use it with custom components. thank you for your help!

解决方案

I was able to get this to work using the Angular ComponentFactoryResolver. There's a bit of setup, but once you get it working, you can use it to render any component you want (and put it anyplace you'd like...including a mapbox popup).

I'm not sure if this is still the "right" way to do this (I'm still on Angular v5) but it does work.

1) Create Dynamic Component Service (can't recall where I got this...sorry for no attribution whoever you are)

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) Use the service to render your custom component in the mapbox-gl popup

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);
...

Just to avoid any confusion, the custom popup component might look something like:

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>

这篇关于Mapbox GL Popup使用自定义标记设置内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆