我可以上传文件并成功上传到Firebase存储。但是,当我将src绑定到下载URL时,出现以下错误:null:1 GET http://localhost:4200/null 404(未找到)
我想要一个占位符图像来消除此错误。我似乎无法将我的字符串分配给Observable类型。您会建议做什么呢?
file-upload.component.ts
从'@ angular / core'导入{Component,OnInit}; 从'angularfire2 / storage'导入{AngularFireStorage,AngularFireUploadTask}; 从'../../../node_modules/rxjs'导入{Observable,Subject}; 从'../../../node_modules/angularfire2/firestore'导入{AngularFirestore}; 从'rxjs / operators'导入{finalize};
@Component({
selector: 'file-upload',
templateUrl: './file-upload.component.html',
styleUrls: ['./file-upload.component.css']
})
export class FileUploadComponent {
task: AngularFireUploadTask;
percentage: Observable<number>;
snapshot: Observable<any>;
downloadURL: Observable<string | null> ;
constructor(private storage: AngularFireStorage, private db: AngularFirestore) {
this.downloadURL = 'http://via.placeholder.com/350x150';
}
fileUpload(event){
const file = event.target.files[0];
const filePath = `test/${new Date().getTime()}_${file.name}`;
const fileRef = this.storage.ref(filePath);
const task = this.storage.upload(filePath, file);
//observe percentage changes
this.percentage = task.percentageChanges();
//get notified when the download URL is available
task.snapshotChanges().pipe(
finalize(
() => {
this.downloadURL = fileRef.getDownloadURL();
}
)
)
.subscribe();
}
}
file-upload.component.html
<div class="container">
<div class="card">
<div class="card-header">
Firebase Cloud Storage & Angular 5
</div>
<div class="card-body">
<h5 class="card-title">Select a file for upload:</h5>
<input type="file" (change)="fileUpload($event)" accept=".png,.jpg" />
</div>
<div class="progress">
<div class="progress-bar progress-bar-striped bg-success" role="progressbar" [style.width]="(percentage | async) + '%'" [attr.aria-valuenow]="(percentage | async)" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<img *ngIf="downloadURL != null" [src]="downloadURL | async" />
</div>
</div>
答案 0 :(得分:4)
您可以使用BehaviorSubject,这比每次从字符串创建可观察对象要容易得多。
downloadURL: BehaviorSubject<string>;
在您的建筑中:
construction () {
this.downloadURL = new BehaviorSubject<string>('http://via.placeholder.com/350x150');
}
准备获取真实图像时:
task.snapshotChanges().pipe(
finalize(
() => {
const dlImage = fileRef.getDownloadURL();
this.downloadURL.next(dlImage);
}
)
)
.subscribe();
以及您的HTML:
<img src="{{downloadURL | async}}" />
编辑-
我不知道他们在上次更新中更改了上传功能。因此我们可以对其进行编辑并使用“哑巴”但可以肯定的方式。忽略答案的第一部分,只需编辑代码即可。
在HTML中:
<img src="{{(downloadURL | async) || placeHolder}}" />
,然后添加新的占位符:
placeHolder:string = 'http://via.placeholder.com/350x150';
因此,它将异步等待从存储中下载URL(这是Observable),直到那时,它只会放置我们提供的自定义placeHolder。
答案 1 :(得分:0)
我的图片上传器位于一个与ngModel productModel绑定的表单中,这使我可以使用ngIf
<img
*ngIf="productModel.product_image"
class="card-img-top"
src="{{ oshopUrl }}uploads/{{ this.whichProdImg() }}"
alt="Card image cap"
/>
当我上传图像时,我的函数whichProdImg具有条件,因为我使用相同的形式进行更新,这意味着可能存在图像文件名:
public returnedWhichProdImg = "";
whichProdImg() {
if (this.urlArr[2]) {
this.returnedWhichProdImg = this.urlArr[2];
} else {
this.returnedWhichProdImg = this.productModel.product_image;
}
return this.returnedWhichProdImg;
}
在最终用户单击“上传”按钮时调用的onSubmit函数中,我只需要图像的名称,而不是整个路径,因此我使用split可以使用的最后一个元素。数组:
this.urlArr = this.productModel.fileToUpload.split("\\");
希望有帮助