我尝试使用节点的fs模块加载一些图像。我让它在单个图像上工作,但在ngFor循环中执行此操作的正确方法是什么?
目前我有:
<div *ngFor="let job of getJobs() | async">
<img src={{readImageFile(job.thumbUrl)}}>
</div>
getJobs()从我的服务中返回一个observable。
readImageFile()调用Meteor服务器端方法,该方法使用fs加载图像数据并以异步方式返回:
readImageFile(url) {
if (url) {
this.call('readImageFile', url, function(err, res) {
if (err) {
console.log(err);
}
else {
console.log('read image file success');
return "data:image/jpg;base64," + res;
}
});
}
}
这不起作用..那么在ngFor循环中异步加载数据的正确方法是什么?
更新
我尝试了readImageFile(url) | async
readImageFile: function(url) {
var Future = Npm.require('fibers/future');
var myFuture = new Future();
fs.readFile(String(url),
function read(error, result) {
if(error){
myFuture.throw(error);
} else {
myFuture.return(new Buffer(result).toString('base64'));
}
});
return myFuture.wait();
}
答案 0 :(得分:2)
这不是一个好方法。每次更改检测运行都会调用readImageFile(job.thumbUrl)
,这通常很常见。
这应该有效
<img [src]="readImageFile(job.thumbUrl) | async">
| async
管道应该阻止更改检测重复调用readImageFile()
。
另一种方法是填充数组并绑定到此数组
getJobs() {
this.jobs = /*code to get jobs*/.map(jobs => {
this.images = new Array(jobs.length);
jobs.forEach(item, idx => {
readImageFile(idx, item.thumbUrl);
});
return jobs;
});
}
readImageFile(idx, url) {
if (url) {
this.call('readImageFile', url, (err, res) => {
if (err) {
console.log(err);
}
else {
console.log('read image file success');
this.images[idx] = "data:image/jpg;base64," + res;
}
});
}
}
<div *ngFor="let job of jobs | async; let idx=index">
<img [src]="images[idx]">
</div>