任意位置在Angular 4/Force ViewChild检测中的组件渲染
我的Angular 4应用程序使用第三方库(mapbox)在页面上呈现内容。该库有一个弹出式对话框功能,允许当用户点击地图上的一个引脚来显示弹出窗口: https://www.mapbox.com/mapbox-gl-js/example/popup-on-click/任意位置在Angular 4/Force ViewChild检测中的组件渲染
弹出叫做的东西,如下面的代码:
map.on('click', 'places', function (e) {
new mapboxgl.Popup()
.setLngLat(e.features[0].geometry.coordinates)
.setHTML('<div>this is a popup</div>')
.addTo(map);
});
我想将一个Angular 4+组件呈现到弹出式div中。我试过的东西:
1)将@ViewChild绑定到该弹出的div。
// in the component that holds the map component
@ViewChild("pop", { read: ViewContainerRef }) childContainer: ViewContainerRef;
//when the user clicks the popup
popup.setHTML("<div #pop></div>")
的childContainer
从未分配。我试过在弹出窗口打开后等待几秒钟,或者在组件的ChangeDetectorRef
上调用detectChanges()
。我试过在NgZone.runOutsideAngular()
中打开弹出窗口,然后手动运行detectChanges()
。
如果我手动将div添加到我的html模板,弹出窗口按预期呈现到div的位置。
2)使用工厂到一个div与ID
//when the user clicks the popup
popup.setHTML("<div id="pop">HERE</div>")
const element = this.elRef.nativeElement.querySelector("#pop"); //this is found
const factory = this.componentFactoryResolver.resolveComponentFactory(PopupComponent);
const component = factory.create(this.viewContainerRef.injector, null, element);
在div的内容该处与<!---->
替换渲染它。很明显,Angular会将的东西渲染到该位置,但不是实际的组件。我需要不同的注射器吗?
3)放置部件渲染元素直接进入弹出:
popup.setHTML("<popup-component></popup-component>")
它从未关闭自身成实际成分。即使有像detectChanges()
或NgZone
这样的东西也会运行。
4)有没有其他想法?如何将Angular组件渲染到在Angular之外定义的任意html位置?
我能够使用标准.append
呼叫解决此问题。我不喜欢这个解决方案,但它似乎工作,没有太多的缺点,所以我在这里发布它,以防其他人发现这个问题。
到同一页面添加一个隐藏的组件为您的地图:由ID传递给信息流行组件类属性
//map.component.html
<div id="map"></div>
<div style="display:none">
<info-popup #infopop [id]="selectedId" [renderTo]="popupLocation"></info-popup>
</div>
绑定点击弹出上述
//map.component.ts
popupLocation: any;
selectedId: any;
initializeMap(): void {
this.map.on("click", "pinLayer", (e: MapMouseFeaturesEvent) => {
this.selectedId = e.features[0].properties["id"]; // assumes a distinct id per pin
new mapboxgl.Popup({ closeButton: false })
.setLngLat(e.lngLat)
.setHTML("<div id='popupLocation'></div>")
.addTo(this.map);
this.popupLocation = this.elementRef.nativeElement.querySelector("#popupLocation);
});
}
使用组件与追加:
//infopop.component.ts
export class InfoPopupComponent implements OnChanges {
@Input() id: string;
@Input() renderTo: any;
constructor(private elementRef: ElementRef) { }
ngOnChanges(changes: SimpleChanges): void {
if ("id" in changes) {
// load popup specific details and render
}
if (this.renderTo) {
this.renderTo.append(this.elementRef.nativeElement);
}
}
}
这与绑定的[click]事件infopop.component.ht毫升正确通过。
你可以创建一个笨蛋。我相信你的复杂性可以很容易实现。 [**儿童模态与ViewChild **]的示例(https://stackoverflow.com/questions/42735858/ng2-bootstrap-show-hide-modal-as-child-component/42736058#42736058) – Aravind