【问题标题】:Angular2 binding error "Cannot read property 'size' of undefined"Angular2 绑定错误“无法读取未定义的属性‘大小’”
【发布时间】:2018-10-30 17:49:09
【问题描述】:

我正在尝试克隆 https://imageresize.org/ 以练习 Angular 5。 但是,我遇到了一个问题,它阻止我将 typescript 文件中的值绑定到 html。

这是输入:

<input type="file" accept="image/*" autocomplete="off" style="display: none" id="input" draggable="true" (change)='changeInput()' multiple>

我也在使用xkeshi的图片压缩器(https://github.com/xkeshi/image-compressor)来压缩图片:

changeInput() {
    this.img = <HTMLImageElement>document.querySelector('img,#image');
    this.files = (<HTMLInputElement>document.querySelector('input[type=file],#input')).files
    this.inputFlag = true;
    for (var i = 0; i < this.files.length; i++) {
      var imageCompressor = new ImageCompressor;
      imageCompressor.compress(this.files[i],{
        quality: .4
      }).then((result)=>{
        this.results[i] = result;
        this.resultSize = result.size;
        this.sizeRound = `${Math.round(100 - this.resultSize * 100 / this.fileSize)}%`;
      })
    }
  }

results 是一个 Blob 数组,用于在循环中获取“result”的值:

results: Blob[] = [];

HTML 绑定:

<tr *ngFor ="let file of files, let i = index">
                  <td style="height: 30px"  class="text-center">{{file.name.slice(0,7)}}</td>
                  <td style="height: 30px"  class="text-center">{{status}}</td>
                  <td style="height: 30px"  class="text-center"></td>
                  <td style="height: 30px"  class="text-center">{{file.size}}</td>
              <td style="height: 30px"  class="text-center">{{results[i].size}}</td>
              <td style="height: 30px"  class="text-center">{{sizeRound}}</td>
            </tr>

我得到的错误: a printscreen of the error 有谁知道如何解决这个问题?谢谢你。 p/s: 对不起我的英语,我不是母语人士

【问题讨论】:

  • 你的files数组包含什么?
  • 检查'this.files'中的内容,如果为空'return false'。
  • 我在 results[] 数组中遇到错误,'files' 是一个保存输入文件值的 FileList 类型,现在可以正常工作
  • 您是否尝试在files 模型中设置results,如下所示:this.files[i].results = result; 并在您的html 中设置{{file?.results.size}}。这对你有帮助吗??????
  • @Sanoj_V 我无法设置this.files[i].results = result,因为结果不属于文件类型

标签: javascript angular binding ngfor


【解决方案1】:

据我了解,当值可能不可用时,角度会在组件启动时立即开始放置值。 因此,对象上确实不存在大小,或者其值目前不可用。

尝试使用可选值:

<td style="height: 30px"  class="text-center">{{file?.size}}</td>

【讨论】:

  • 谢谢,但“文件”运行良好。我得到的错误是在这一行:&lt;td style="height: 30px" class="text-center"&gt;{{results[i].size}}&lt;/td&gt;
【解决方案2】:

您可以先使用条件运算符检查数组是否为 != null,然后再尝试访问它。

<td style="height: 30px"  class="text-center">{{results ? results[i]?.size : null}}</td>

【讨论】:

  • 感谢您的帮助,但它只会阻止浏览器引发错误。您知道为什么在这种情况下未定义结果的值吗?因为如果我 console.log 在 typescript 文件中,仍然有一个值。
  • 可以放个console.log的截图吗?
【解决方案3】:

这可能是由于 Angular 中的异步问题,“结果”尚未如您预期的那样导出。

<td style="height: 30px"  class="text-center">{{results ? results[i]?.size : null}}</td>

同样在组件中,通过如下方法显式调用结果。

changeInput() {
    this.img = <HTMLImageElement>document.querySelector('img,#image');
    this.files = (<HTMLInputElement>document.querySelector('input[type=file],#input')).files
    this.inputFlag = true;
    for (var i = 0; i < this.files.length; i++) {
      var imageCompressor = new ImageCompressor;
      imageCompressor.compress(this.files[i],{
        quality: .4
      }).then((result)=>{
        //this.results[i] = result;
        this.refreshResults(i, result);
        console.log(this.results);
        this.resultSize = result.size;
        this.sizeRound = `${Math.round(100 - this.resultSize * 100 / this.fileSize)}%`;
      })
    }
  }

refreshResults(index, result) {
    this.results[index] = result;
}

【讨论】:

  • 谢谢,imo我正面临一些异步问题tbh,但我不知道如何解决它。但是,refreshResults 方法的“结果”从何而来?应该是refreshResults(index,result) { this.results[index] = result; }吧?
  • 并在 changeInput: console.log(this.refreshResults(i,result)); 但是,这将控制台输出“未定义”值
  • 是的,您还需要将结果作为参数传递。将结果分配给 this.results[index] 后,只需 console.log this.results[index]。这应该可以正常工作。也编辑了我的答案。
  • 谢谢,但不知何故 html 仍然无法获取 results 的值 :(
猜你喜欢
  • 2017-05-05
  • 2021-02-05
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
  • 2017-06-18
  • 1970-01-01
相关资源
最近更新 更多