我有一个 Angular 18 项目,它从 API 中提取图像数据并将其显示在屏幕上。有人可以帮助我理解这种行为吗?
应用程序在 ImageService.ts 的 getImage(..) 函数中使用“const a = document.createElement('a');”抛出异常“文档未定义” 文件。即使出现此错误,应用程序也会提取图像数据并将其绘制在页面上。
当我取出这条线时,我收到了不同的错误,并且图像也没有显示。
我在 API 上添加了一个断点,还在 ImageService.ts 中的 getImage 函数上添加了一个断点,当我刷新页面时,服务器 API 断点甚至在 getImage 函数中的断点之前被命中。
是否有一种新的方式来服务 Observable 或者这可能是与角度钩子相关的问题?
图像服务.ts
@Injectable({
providedIn: 'root'
})
export class ImageService {
private apiUrl = 'http://localhost:5189/LoadImage';
constructor(private http: HttpClient) { }
getImage(objectId: string): Observable<Blob> {
const a = document.createElement('a');
return this.http.get(`${this.apiUrl}/${objectId}`, {responseType: 'blob' });
}
}
图像.component.ts
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.css'],
standalone: true,
imports:[CommonModule]
})
export class ImageComponent implements OnInit {
imageUrl: any;
constructor(private imageService: ImageService) {}
async ngOnInit(): Promise<void> {
(await this.imageService.getImage('apple')).subscribe({
next: (blob) => {
const objectURL = URL.createObjectURL(blob);
this.imageUrl = objectURL;
}}
);
}
}
}
Image.component.html:
<div>
<img [src]="imageUrl" alt="Image" />
</div>
App.component.html
<app-image></app-image>
在服务器上,
document
和window
对象并不像浏览器中那样存在,因此涉及这些对象的某些功能将无法工作。
createObjectUrl 似乎与
document
和 window
对象相关联,因此问题正在发生。
要解决这个问题,您必须确保此逻辑仅在浏览器上执行。
我们为此提供了两种工具。
当我们只想在浏览器上渲染 HTML 时,可以使用
defer
。
当我们只想在浏览器上运行组件代码时,可以使用
afterNextRender
。
因此您可以将代码更新为。
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.css'],
standalone: true,
imports: [CommonModule],
})
export class ImageComponent implements OnInit {
imageUrl: any = 'https://placehold.co/600x400'; // show some loading image here!
constructor(private imageService: ImageService) {}
ngOnInit() {
afterNextRender(() => this.loadImage()); // runs only on browser
}
loadImage() {
this.imageService.getImage('apple').subscribe({
next: (blob: Blob) => {
const objectURL = URL.createObjectURL(blob);
this.imageUrl = objectURL;
},
});
}
}