#javascript #angular #blob #jszip
#javascript #angular #большой двоичный объект #jszip
Вопрос:
Я анализирую zip-файл с изображениями, на которые я хочу ссылаться с помощью blobURL в filesFromZip
объекте, и выполняю итерацию по нему с помощью ngFor, чтобы отобразить изображения на странице.
Это выглядит так
filesFromZip = {};
let zip = new JSZip();
zip.loadAsync(zipfileFromInput)
.then(function (zip) {
for (let file in zip.files) {
let fileInZip = zip.files[file];
zip.file(fileInZip.name)
.async("arraybuffer")
.then(function (content) {
let buffer = new Uint8Array(content);
let blob = new Blob([buffer.buffer]);
// here is where I want to push this object into the filesFromZip object somehow....
return {
fileName: fileInZip.name,
blobURL: URL.createObjectURL(blob)
};
});
}
});
в шаблоне:
<md-card *ngFor="let file of filesFromZip">
<h3 md-line>{{file.fileName}}</h3>
<img src="{{file.blobURL}}">
</md-card>
Как я могу получить данные из promise в filesFromZip
?
Я пытался просто вставить его в filesFromZip
, но это выдает мне эту ошибку:
error_handler.js:47 ИСКЛЮЧЕНИЕ: Неперехваченный (в promise): ошибка типа: не удается прочитать свойство ‘async’, равное нулю
Я действительно борюсь с асинхронностью и Angular 2. Кто-нибудь, кто может направить меня в правильном направлении?
Ответ №1:
Во-первых, вы не можете выполнять итерацию по простому объекту с *ngFor
директивой, поэтому filesFromZip
должен быть массив.
this.filesFromZip = [];
zip.loadAsync(zipfileFromInput)
.then((zip)=> {
for (let file in zip.files) {
let fileInZip = zip.files[file];
zip.file(fileInZip.name)
.async("arraybuffer")
.then((content)=> {
let buffer = new Uint8Array(content);
let blob = new Blob([buffer.buffer]);
// here is where I want to push this object into the filesFromZip object somehow....
this.filesFromZip.push({
fileName: fileInZip.name,
blobURL: URL.createObjectURL(blob)
});
});
}
});
или вы можете использовать Promise.all(), который создаст promise из итерации Promise, а затем использует асинхронный канал :
javascript :
this.filesFromZip = Promise.all(
zip.loadAsync(zipfileFromInput)
.then((zip)=> {
let out=[];
for (let file in zip.files) {
let fileInZip = zip.files[file];
out.push(zip.file(fileInZip.name)
.async("arraybuffer")
.then((content)=> {
let buffer = new Uint8Array(content);
let blob = new Blob([buffer.buffer]);
// here is where I want to push this object into the filesFromZip object somehow....
this.filesFromZip.push({
fileName: fileInZip.name,
blobURL: URL.createObjectURL(blob)
});
}));
}
return out;
});
)
шаблон :
<md-card *ngFor="let file of filesFromZip|async">
<h3 md-line>{{file.fileName}}</h3>
<img src="{{file.blobURL}}">
</md-card>
Однако ваша главная проблема здесь, похоже, заключается в том, что zip.file(fileInZip.name)
возвращается null
Комментарии:
1. Чтобы использовать асинхронный канал, не должен ли filesFromZip возвращать promise, а не так, как я сейчас пытаюсь вернуть объект?
2. Просто новый пустой объект, в который я пытался вставить результат из promise
3. вы имеете в виду этот результат:
return { fileName: fileInZip.name, blobURL: URL.createObjectURL(blob) };
? Потому что, поскольку это возвращается обещанием, оно станет обещанием…4. Да, я пытался вставить этот объект для каждого файла в filesFromZip вместо его возврата, но он выдал ошибку. Но теперь возвращаемый объект живет только в promise, и я не знаю, как получить его в filesFromZip
5. Откуда берется эта
filesFromZip
переменная !!!??? Пожалуйста, отредактируйте свой вопрос со всей необходимой информацией…