Angular2 - 在ngFor中异步加载二进制图像数据

时间:2016-11-02 09:02:11

标签: image asynchronous angular binary observable

我尝试使用节点的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(); 
}

1 个答案:

答案 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>