我正在使用AGM (Angular Google Maps),我想创建一组我自己的自定义组件,包装AGM组件,以允许在我的应用程序中高度重用。
然而,当我这样做时,标记(在本例中)似乎没有呈现在地图上,但我没有得到任何错误。我想知道这是否与在<ng-content>
中嵌套组件有关
有人能帮上忙吗?我有一个stackblitz设置。请看底部使用Slot
的Angular 7 Stackblitz的更新。
当我嵌套自定义组件时,它创建了一个ng-content
元素中间人,这似乎破坏了agm
功能。
我的核心组件是vmap
@Component({
selector: "v-map",
template: `<agm-map flex [latitude]="lat" [longitude]="lng">
<ng-content></ng-content>
<!--agm-marker [latitude]="lat" [longitude]="lng"></agm-marker-->
</agm-map>`
})
export class VMapComponent {
lat: number = 51.678418;
lng: number = 7.809007;
constructor(private loader: MapsAPILoader) {
}
}
请注意,如果我在模板中的agm-marker
中返回注释,它将呈现。它似乎只有在ng-content
中才不起作用。
下面是v-map-plots
子组件
@Component({
selector: "v-map-plots",
template: `<agm-marker *ngFor="let plot of plots" [latitude]="plot.Latitude" [longitude]="plot.Longitude"></agm-marker>`
})
export class VMapPlotsComponent {
@Input() plots: IPlot[] = [];
constructor(@Host() private parent: VMapComponent) {
this.plots.push({ Latitude: 51.678418, Longitude: 7.809007 })
}
}
这是年度股东大会问题还是角度问题?这与ng-content
有关吗?有没有办法绕过它?
根据@Anytoe的评论,更新这里是我的用例:
<v-map>
<v-map-plots [plots]="displayPlots"></v-map-plots>
</v-map>
我的想法是,我可以制作一些可重用的地图组件,然后我可以在我的应用程序中需要的地方重用这些组件。
更新2我读到了关于插槽的信息,认为这可以帮助我,所以设置了一个新的Stackblitz for Angular 7和使用过的插槽,但也无法让它工作
发布于 2019-02-21 16:57:14
首先,如果你在Angular生态系统下工作,我会建议你使用ng-content并利用它的所有功能。Slot标签用于将内容投射到HTML5模板标签中,功能相当相同,但如果您在Angular环境下使用ng-content,则使用ng- content更加强大和通用。
上面说,我已经看过你的堆栈闪电战了,上面写着没有MarkerManager的提供商。这意味着在创建AgmsMarkers时,不会实例化MarkerManager提供程序。
我搜索了一下,我看到用这种方式组成组件,使用v-map和v-map-plot,创建的顺序是下一个:
1- v-map
2- v-map-plots
3- agm-marker
4- agm-map
Angular首先在v-AgmMarker上创建投影内容,因此在AgmMap之前创建AgmMarker。这就是没有MarkerManager提供程序的原因,因为它是由AgmMap组件创建的。
在这种情况下,我只需简单地对agm-map进行非包装。我认为它不会对您正在尝试做的事情产生影响,因为您可以在内部编写任意多的组件,如下所示:
<agm-map flex [latitude]="lat" [longitude]="lng">
<v-map-plots></v-map-plots>
</agm-map>
我把你的堆栈闪电战变成了一个分叉:https://stackblitz.com/edit/angular-7-master-7jvsjr
希望这能有所帮助!
发布于 2019-02-22 06:15:24
正如在另一个答案中已经描述的那样,问题是AGM库的设计不能与内容投影一起工作。当您在本例中使用它时,content元素是在包装它的组件之前创建的,这在本例中不起作用,因为agm-marker-elements
是首先创建的,并且它们需要来自尚未创建的agm-map
组件的服务。它是在准备好内容之后创建的。
我建议另一个变通的解决方案,让你保留你的设计。对于这个解决方案,您将v-map-plots
组件更改为一个指令,这样它就不会有任何呈现。这意味着您不需要任何内容投影,只需通过在v-map
组件中使用@ContentChildren
装饰器就可以获得所有的v-map-plots
指令。然后使用指令中的数据在v-map
组件中呈现agm-map
和agm-markers
。
这看起来是这样的:
@Directive({
selector: "v-map-plots"
})
export class VMapPlotsDirective {
plots: IPlot[] = [];
constructor(@Host() @Inject(forwardRef(() => VMapComponent)) private parent: VMapComponent) {
this.plots.push({ Latitude: 51.678418, Longitude: 7.809007 })
console.log("yo", this.plots);
}
}
@Component({
selector: "v-map",
template: `<agm-map flex [latitude]="lat" [longitude]="lng">
<ng-container *ngFor="let vMapPlotsDirective of vMapPlotsDirectives">
<agm-marker *ngFor="let plot of vMapPlotsDirective.plots" [latitude]="plot.Latitude" [longitude]="plot.Longitude"></agm-marker>
</ng-container>
</agm-map>`
})
export class VMapComponent {
lat: number = 51.678418;
lng: number = 7.809007;
@ContentChildren(VMapPlotsDirective) vMapPlotsDirectives;
constructor(private loader: MapsAPILoader) {
}
}
下面是它在StackBlitz中的一个实现,这样您就可以看到它的实际效果。
https://stackoverflow.com/questions/53049510
复制相似问题