如何将图像 base64 url 传递给兄弟组件
How to pass an image base64 url to a sibling component
我有一个可以完美呈现传单地图的组件,我可以在上面绘制一些多边形。我添加了 htmlToImage 库来截取我所绘制的内容的屏幕截图,如果我将它作为子项附加到同一组件,它会呈现得很好。但我喜欢将该图像源传递给下一个组件(同级组件)并在其上做其他事情。我尝试实现一项服务,我的第一个组件将 dataURL 写入字符串变量,第二个组件获取该变量并使用它来显示来自该存储路径的图像。第一个组件使用 router-link 方法作为同级组件路由到下一个组件(从 home/map 到 home/image),但它不会显示图像,只显示 console.log(path) 是空字符串,最初是我在服务中初始化的。我做错了什么?
我在本地主机上使用 Angular 9 和 运行。到目前为止,这是我尝试过的:
map.component.ts
// Map related methods ....
// ....
getScreenshot() {
htmlToImage.toPng(document.getElementById('map'))
.then((dataUrl) => {
this.projectService.setProject('image', dataUrl);
})
.catch((error) => {
console.error('oops, something went wrong!', error);
});
}
screenshot.component.ts
const path = this.projectService.getProject().image;
constructr(private projectService: ProjectService) {}
screenshot.component.html
<div class="row content">
<img [src]="path" alt="map" >
</div>
project.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
private project = {
title: '',
image: '',
};
getProject() {
return this.project;
}
setProject(option: any, value: any) {
this.project[option] = value;
}
}
app-routing.module.ts
export const appRoutes: Routes = [
{
path: 'home', component: AppComponent,
children: [
{ path: 'map', component: MapComponent },
{ path: 'image', component: ScreenshotComponent },
]
},
];
我已经在 StackBlitz 上发布了我的代码。
我在 MapComponent
中创建了一个示例地图,并按照 ngx-leaflet-draw and ngx-leaflet 的文档在地图中绘制多边形。在 /home/map
路线中创建多边形后,我将带有多边形的图像存储到 ProjectService
中,以便在通过 [=20] 按钮进入 /home/image
路线后将其放入 ScreenshotComponent
=]指令。
我试图用方法名称进行描述,以便轻松查看正在发生的事情。
map.component.html
<div style="height: 300px; width: 600px;"
id="map"
leaflet
leafletDraw
(leafletMapReady)="onMapReady($event)"
(leafletDrawCreated)="onLeafletDrawCreated($event)"
[leafletOptions]="leafletOptions"
[leafletDrawOptions]="drawOptions"
>
</div>
<div>Draw a polygon and go to image route</div>
<button routerLink="/home/image">Go Image Page</button>
map.component.ts
import { Component } from "@angular/core";
import htmlToImage from "html-to-image";
import { ProjectService } from "../project.service";
import * as L from 'leaflet';
@Component({
selector: "app-map",
templateUrl: "./map.component.html",
styleUrls: ["./map.component.css"]
})
export class MapComponent {
map: L.Map;
editableLayers = new L.FeatureGroup();
leafletOptions = {
layers: [
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18 })
],
zoom: 5,
center: L.latLng(46.879966, -121.726909)
};
drawOptions = {
position: 'topright',
draw: {
marker: {
icon: L.icon({
iconSize: [ 25, 41 ],
iconAnchor: [ 13, 41 ],
iconUrl: 'assets/marker-icon.png',
shadowUrl: 'assets/marker-shadow.png'
})
},
polyline: false,
circle: {
shapeOptions: {
color: '#aaaaaa'
}
}
}
};
constructor(private projectService: ProjectService) {}
onMapReady(map: L.Map) {
// map loaded, store in map var
this.map = map;
}
onLeafletDrawCreated(event: any) {
// after drawing a polygon take a screenshot
this.getScreenshot();
}
getScreenshot() {
// I recommend you use Renderer2 provided by Angular Core Package instead of document.getElementById directly
// https://angular.io/api/core/Renderer2
htmlToImage
.toPng(document.getElementById("map"))
.then(dataUrl => {
this.projectService.setProject("image", dataUrl);
})
.catch(error => {
console.error("oops, something went wrong!", error);
});
}
}
screenshot.component.html
<div *ngIf="path; else noImageTemplate;"
style="height: 300px; width: 600px;" class="row content">
<img style="height: 100%; width: 100%; object-fit: contain;" [src]="path" alt="map" >
</div>
<ng-template #noImageTemplate>
<div style="height: 300px; width: 600px; border: 1px solid lightgray;">
No image yet, try select some polygon on map page
</div>
</ng-template>
<button routerLink="/home/map">Go Map Route</button>
screenshot.component.ts
import { Component, OnInit } from '@angular/core';
import { ProjectService } from "../project.service";
@Component({
selector: 'app-screenshot',
templateUrl: './screenshot.component.html',
styleUrls: ['./screenshot.component.css']
})
export class ScreenshotComponent implements OnInit {
path: string = this.projectService.getProject().image;
constructor(private projectService: ProjectService) {}
ngOnInit() {
console.info('path from project service!', this.path);
}
}
project.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
private project = {
title: '',
image: '',
};
getProject() {
return this.project;
}
setProject(option: any, value: any) {
this.project[option] = value;
}
}
此处提供解决方案:Stackblitz
我有一个可以完美呈现传单地图的组件,我可以在上面绘制一些多边形。我添加了 htmlToImage 库来截取我所绘制的内容的屏幕截图,如果我将它作为子项附加到同一组件,它会呈现得很好。但我喜欢将该图像源传递给下一个组件(同级组件)并在其上做其他事情。我尝试实现一项服务,我的第一个组件将 dataURL 写入字符串变量,第二个组件获取该变量并使用它来显示来自该存储路径的图像。第一个组件使用 router-link 方法作为同级组件路由到下一个组件(从 home/map 到 home/image),但它不会显示图像,只显示 console.log(path) 是空字符串,最初是我在服务中初始化的。我做错了什么?
我在本地主机上使用 Angular 9 和 运行。到目前为止,这是我尝试过的:
map.component.ts
// Map related methods ....
// ....
getScreenshot() {
htmlToImage.toPng(document.getElementById('map'))
.then((dataUrl) => {
this.projectService.setProject('image', dataUrl);
})
.catch((error) => {
console.error('oops, something went wrong!', error);
});
}
screenshot.component.ts
const path = this.projectService.getProject().image;
constructr(private projectService: ProjectService) {}
screenshot.component.html
<div class="row content">
<img [src]="path" alt="map" >
</div>
project.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
private project = {
title: '',
image: '',
};
getProject() {
return this.project;
}
setProject(option: any, value: any) {
this.project[option] = value;
}
}
app-routing.module.ts
export const appRoutes: Routes = [
{
path: 'home', component: AppComponent,
children: [
{ path: 'map', component: MapComponent },
{ path: 'image', component: ScreenshotComponent },
]
},
];
我已经在 StackBlitz 上发布了我的代码。
我在 MapComponent
中创建了一个示例地图,并按照 ngx-leaflet-draw and ngx-leaflet 的文档在地图中绘制多边形。在 /home/map
路线中创建多边形后,我将带有多边形的图像存储到 ProjectService
中,以便在通过 [=20] 按钮进入 /home/image
路线后将其放入 ScreenshotComponent
=]指令。
我试图用方法名称进行描述,以便轻松查看正在发生的事情。
map.component.html
<div style="height: 300px; width: 600px;"
id="map"
leaflet
leafletDraw
(leafletMapReady)="onMapReady($event)"
(leafletDrawCreated)="onLeafletDrawCreated($event)"
[leafletOptions]="leafletOptions"
[leafletDrawOptions]="drawOptions"
>
</div>
<div>Draw a polygon and go to image route</div>
<button routerLink="/home/image">Go Image Page</button>
map.component.ts
import { Component } from "@angular/core";
import htmlToImage from "html-to-image";
import { ProjectService } from "../project.service";
import * as L from 'leaflet';
@Component({
selector: "app-map",
templateUrl: "./map.component.html",
styleUrls: ["./map.component.css"]
})
export class MapComponent {
map: L.Map;
editableLayers = new L.FeatureGroup();
leafletOptions = {
layers: [
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18 })
],
zoom: 5,
center: L.latLng(46.879966, -121.726909)
};
drawOptions = {
position: 'topright',
draw: {
marker: {
icon: L.icon({
iconSize: [ 25, 41 ],
iconAnchor: [ 13, 41 ],
iconUrl: 'assets/marker-icon.png',
shadowUrl: 'assets/marker-shadow.png'
})
},
polyline: false,
circle: {
shapeOptions: {
color: '#aaaaaa'
}
}
}
};
constructor(private projectService: ProjectService) {}
onMapReady(map: L.Map) {
// map loaded, store in map var
this.map = map;
}
onLeafletDrawCreated(event: any) {
// after drawing a polygon take a screenshot
this.getScreenshot();
}
getScreenshot() {
// I recommend you use Renderer2 provided by Angular Core Package instead of document.getElementById directly
// https://angular.io/api/core/Renderer2
htmlToImage
.toPng(document.getElementById("map"))
.then(dataUrl => {
this.projectService.setProject("image", dataUrl);
})
.catch(error => {
console.error("oops, something went wrong!", error);
});
}
}
screenshot.component.html
<div *ngIf="path; else noImageTemplate;"
style="height: 300px; width: 600px;" class="row content">
<img style="height: 100%; width: 100%; object-fit: contain;" [src]="path" alt="map" >
</div>
<ng-template #noImageTemplate>
<div style="height: 300px; width: 600px; border: 1px solid lightgray;">
No image yet, try select some polygon on map page
</div>
</ng-template>
<button routerLink="/home/map">Go Map Route</button>
screenshot.component.ts
import { Component, OnInit } from '@angular/core';
import { ProjectService } from "../project.service";
@Component({
selector: 'app-screenshot',
templateUrl: './screenshot.component.html',
styleUrls: ['./screenshot.component.css']
})
export class ScreenshotComponent implements OnInit {
path: string = this.projectService.getProject().image;
constructor(private projectService: ProjectService) {}
ngOnInit() {
console.info('path from project service!', this.path);
}
}
project.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
private project = {
title: '',
image: '',
};
getProject() {
return this.project;
}
setProject(option: any, value: any) {
this.project[option] = value;
}
}
此处提供解决方案:Stackblitz