angular - Đối số kiểu 'HTMLElement' không thể gán cho tham số kiểu 'CanvasImageSource'
Tôi đang cố gắng để cùng một hình ảnh được tải vào tất cả các canvas trong HTML của tôi. Trước đây tôi đã viết toàn bộ trang web của mình bằng Javascript nhưng bây giờ tôi đang học Angular và TypeScript.
Tôi đang nhận được lỗi này được đánh dấu trong Visual Studio Code:
Đối số của loại 'HTMLElement' không thể gán cho tham số của loại 'CanvasImageSource'. Loại 'HTMLElement' thiếu các thuộc tính sau của loại 'HTMLVideoElement': height, msHorizontalMirror, msIsLayoutOptimalForPlayback, msIsStereo3D, và 80 thuộc tính khác.ts(2345)
Nhưng tôi không thấy lỗi nào hiển thị trong bảng điều khiển. Tôi có thể tải hình ảnh lên HTML trong canvas (vậy là nó đang hoạt động).
Đây là ts của tôi:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
constructor() { }
ngOnInit() {
document.querySelectorAll("canvas").forEach(c=>{
var ctx = c.getContext("2d");
var img = document.getElementById("P43");
ctx.drawImage(img,0,0,106,50); //(image, offsetx, offsety, x, y)
});
}
}
VS Code đánh dấu lỗi ở dòng này ctx.drawImage(img,0,0,106,50); //(image, offsetx, offsety, x, y), nó đánh dấu img và hiển thị lỗi.
Tôi đã cố gắng tìm kiếm điều này nhưng những giải pháp duy nhất tôi tìm thấy là khi bạn có ID cho thẻ (tôi không có vì tất cả đều là canvas trên trang) hoặc nếu có một input.
Bất cứ sự giúp đỡ nào cũng được trân trọng.
Câu trả lời #1
Bạn phải nói với trình biên dịch rằng biến img đang được đặt là một HTMLImageElement.
Phương thức ctx.drawImage mong đợi một :
HTMLOrSVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap;
Nếu P43 của bạn là một canvas, bạn phải làm:
const img = document.getElementById("P43") as HTMLCanvasElement;
nếu đó là một phần tử hình ảnh:
const img = document.getElementById("P43") as HTMLImageElement;
Sẽ còn tốt hơn nếu thực sự kiểm tra rằng phần tử đó thực sự là loại Element đúng. Bạn có thể làm điều này với instanceof. Trình biên dịch TypeScript cũng sẽ nhận ra câu lệnh if, và bên trong câu lệnh if biến img sẽ là HTMLCanvasElement đối với trình biên dịch, nên việc ép kiểu rõ ràng không còn cần thiết:
const img = document.getElementById("P43");
if (img instanceof HTMLImageElement) {
ctx.drawImage(img,0,0,106,50);
} else {
// wrong element!
}
Câu trả lời số 2
Bạn cần thông báo cho trình biên dịch TS các loại phần tử HTML cụ thể mà bạn đang sử dụng trong component của mình.
Ở đây bạn đang truy vấn đối tượng tài liệu và lấy một số phần tử cũng như gọi một số phương thức trên các phần tử đó. Vì TypeScript không thể suy ra kiểu của các phần tử này và do đó tạo ra lỗi biên dịch, kiểu cần được chỉ định rõ ràng.
Thử cái này:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
constructor() { }
ngOnInit() {
document.querySelectorAll('canvas').forEach((c: HTMLCanvasElement) => {
const ctx = <CanvasRenderingContext2D> c.getContext('2d');
const img = <HTMLImageElement> document.getElementById('P43');
ctx.drawImage(img, 0, 0, 106, 50);
});
}
}
