我正在寻找将已知/已定义组件注入应用程序根目录并将@Input()选项投影到该组件上的最佳方法.
这对于在应用程序主体中创建模态/工具提示等内容是必要的,这样overflow:hidden/ etc不会扭曲位置或完全切断它.
我发现我可以得到它ApplicationRef然后hackily向上遍历并找到ViewContainerRef.
constructor(private applicationRef: ApplicationRef) {
}
getRootViewContainerRef(): ViewContainerRef {
return this.applicationRef['_rootComponents'][0]['_hostElement'].vcRef;
}
Run Code Online (Sandbox Code Playgroud)
一旦我有了,我就可以调用createComponent如下:
appendNextToLocation<T>(componentClass: Type<T>, location: ViewContainerRef): ComponentRef<T> {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
const parentInjector = location.parentInjector;
return location.createComponent(componentFactory, location.length, parentInjector);
}
Run Code Online (Sandbox Code Playgroud)
但现在我已经创建了组件,但我的所有Input属性都没有完成.为了实现这一点,我必须手动遍历我的选项并在appendNextToLocation实例的结果上设置如下:
const props = Object.getOwnPropertyNames(options);
for(const prop of props) {
component.instance[prop] = options[prop];
}
Run Code Online (Sandbox Code Playgroud)
现在我意识到你可以做一些DI来注入选项,但这使得它在尝试用作普通组件时不可重复使用.这是什么看起来像参考:
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ComponentClass);
let parentInjector = location.parentInjector;
let providers = ReflectiveInjector.resolve([
{ …Run Code Online (Sandbox Code Playgroud) 我使用谷歌地图javascript api,我必须在InfoWindow中显示一个Angular组件.
在我的项目中,我使用该Jsonp服务加载谷歌地图API .比我有google.maps.Map可用的对象.稍后在组件中我创建了一些标记并将一个点击监听器附加到它们:
TypeScript:
let marker = new google.maps.Marker(opts);
marker.setValues({placeId: item[0]});
marker.addListener('click', (ev: google.maps.MouseEvent) => this.onMarkerClick(marker, ev));
Run Code Online (Sandbox Code Playgroud)
然后在click处理程序中我想打开一个包含Angular组件的信息窗口:
TypeScript:
private onMarkerClick(marker: google.maps.Marker, ev: google.maps.MouseEvent) {
var div = document.createElement();
this.placeInfoWindow.setContent(div);
// Magic should happen here somehow
// this.placeInfoWindow.setContent('<app-info-view-element></app-info-view-element>');
this.placeInfoWindow.open(this.map, marker);
}
Run Code Online (Sandbox Code Playgroud)
我最终做的是一些香草JS:
TypeScript:
private onMarkerClick(marker: google.maps.Marker, ev: google.maps.MouseEvent) {
let div = document.createElement('div');
div.className = 'map-info-window-container';
div.style.height = '140px';
div.style.width = '240px';
this.placeInfoWindow.setContent(div);
this.placeInfoWindow.open(this.map, marker);
this.placesService.getPlace(marker.get('id')).subscribe(res => {
this.decorateInfoWindow(div, res.name, …Run Code Online (Sandbox Code Playgroud)