【发布时间】:2019-03-06 01:12:15
【问题描述】:
场景很简单。使用表单上传图片,如果上传成功,刷新相册。我使用 angular6 和 ng-carousel。所有系统都在我的 Windows 10 笔记本电脑中本地设置。
表单被上传,文本数据保存在数据库中,图像保存在节点 8.11.1 的文件中。我将图像保存在src/assets/images 中。我可以看到更改,并且在上传时没有错误。
但是,上传后,我尝试使用新图像的 URL 将其添加为轮播中的最后一张图像,但我得到的只是 404 错误。该 URL 类似于 http://localhost:4200/assets/images/unsplash.jpg 该 URL 有效,图像在那里并且所有其他轮播图像使用相同的 URL。但是,新图像有 404 错误。我必须重新编译角度应用程序才能看到图像。不只是刷新页面,重新编译整个应用程序。
我不知道如何解决这个问题。我尝试在前端使用 File 对象或 HTML5 FileReader API,而不依赖于在图像上传后创建 URL。但是他们没有 URL 并且 ng-carousel 需要像 /assets/images/img.jpg 这样的 URL 才能工作。为了使用某种 URL,我也尝试从节点获取临时 URL 并将其返回给前端,但由于它是 temp 文件夹 URL,浏览器不会让我使用它。我也尝试使用createObjectURL,但并非所有浏览器都支持。我还尝试在保存图像后执行GET 并从数据库中获取所有图像名称,再次循环它们并再次提供轮播模板。没有。仍然是404错误。我必须重新编译应用程序。
发生了什么?这是一个角度6的问题吗?安全限制?请帮我解决这个问题,我不知道如何处理了。
代码大纲。
形式
<form *ngIf="pointPartsActive" [formGroup]="imageUpload" (ngSubmit)="imageUploadSubmitted($event.target)" >
<input type="file" (change)='imageChange($event)' #imageInput id="imageInput" name = 'imageInput' accept=".png, .jpg, .jpeg, .gif" formControlName="imageInput" >
<input type="text" formControlName="imageName" name='imageName' placeholder="name" >
<button type="submit" >Submit</button>
</form>
html轮播模板,添加自定义html也可以当场删除图片。
<ngb-carousel #carousel *ngIf="images" (slide)="onSlide($event)">
<ng-template ngbSlide *ngFor="let im of images; let i = index" id="{{im.id}}">
<img src='../assets/images/{{im.name}}' >
<div class='carousel-img-details'>
<button type="button" (click)='deletepic(im.photoId)'>delete</button>
</div>
</ng-template>
</ngb-carousel>
表单提交
imageUploadSubmitted(form){
let formData = new FormData(form);
let eb =null;
this.http.post('http://localhost:3000/cms/upload',formData,{reportProgress:true,observe:'events'}).subscribe(
event=>{
if(event.type === HttpEventType.Response){
eb = event.body;
if(eb.success){
this.imageUpload.reset();
this.addpic(eb.data);
}
}
});
}
成功提交表单后,更新为轮播提供数据的数组。它是一个简单的 json 对象数组,例如 [{'id':1,'name':'James'},{'id':2,'name':'Nolan'}],并通过 ngFor 提供轮播。
addpic(data){
let slide = null;
this.images.push({
'photoId':Number(data.id)
'id': this.images.length,
'name': data.name
});
//get the id of the last slide and go there :
setTimeout(() => {
slide = this.images[this.images.length-1].id;
this.carousel.select(slide);
});
this.images = this.images.slice(); //try to "refresh" array itself
}
stackblitz中的代码逻辑
谢谢
【问题讨论】:
-
澄清:您是否将图像上传到资产文件夹?当您在本地运行应用程序时,您是使用 ng serve 运行它,还是在 ng build 之后从节点服务器运行它。有两个 assets 文件夹,一个在 src 中,一个在 dist 中,如果您使用 build 运行应用程序,则图像必须在 dist 文件夹中。
-
@Engam 是的。网址是
http://localhost:4200/assets/images/1537906640981-unsplash.jpg -
@Engam 一个 CMD 为节点 8.11.1 运行
nodemon,另一个为 angular6 运行ng serve。我将图像保存在src/assets/images中。我有提到我是新手吗?哦,上帝,这是一些愚蠢的细节,我只是浪费了所有这些时间,也浪费了大家的时间,对吧? -
在选择图像后的 stackblitz 中,我看到此错误:ERROR TypeError: Cannot read property 'nativeElement' of undefined at FileReader.reader.onload (app.component.ts:52)
-
@Kalamarico 我失去了你。在什么功能上?我看到 52 checkfiles 和 readfiles 之间有一个空行。
标签: angular image url file-upload angular6