【问题标题】:Cannot read property ‘0’ of undefined无法读取未定义的属性“0”
【发布时间】:2019-11-20 20:44:51
【问题描述】:

更新:在做了一些调试后,我发现input对象有文件数组,并且包括文件数组的输入元素被正确初始化,但是当它执行input.onChange函数时,输入对象是突然未定义,因此还有 files 数组。

我的应用程序中有一个 tinyMCE 编辑器,以便可以编辑网页并上传视频和图像。不幸的是,我昨天丢失了后端的所有文件。我几乎回到了我离开的地方。现在已经到了上传媒体的地步。尽管前端没有改变,但 TinyMCE 媒体上传停止工作。

罪魁祸首是未定义的this.files[0]。昨天完全相同的代码运行没有问题。即使打字稿编译器也声明它是未定义的,它仍然有效。

TinyMCE init 位于我的nav 组件中:

tinymceInit = {
    plugins: [
      'advlist autolink link image file lists charmap print preview hr anchor pagebreak',
      'searchreplace wordcount visualblocks visualchars insertdatetime media nonbreaking',
      'table contextmenu directionality emoticons paste textcolor responsivefilemanager code'
    ],
    toolbar1: 'undo redo | bold italic underline | alignleft aligncenter alignright alignjustify |' +
      ' bullist numlist outdent indent | styleselect',
    toolbar2: ' link unlink anchor | image media file | forecolor backcolor  | print preview code ',
    image_advtab: true ,
    image_title: true,
    images_reuse_filename: true,
    file_picker_types: 'image media',
    file_picker_callback: (cb, value, meta) => {
      const apiUrl = this.apiService.apiUrl;
      const templateId = this.currTemplateId;
      const input = document.createElement('input');
      input.setAttribute('type', 'file');

      input.onchange = () => {
        console.log('JSDJFSODNVONASDv');
        // @ts-ignore
        const file = this.files[0];
        const fileName = file.name.split('.')[0];
        const reader = new FileReader();
        reader.onload = () => {
          // @ts-ignore
          const blobCache = tinymce.activeEditor.editorUpload.blobCache;
          // @ts-ignore
          const base64 = reader.result.split(',')[1];
          const blobInfo = blobCache.create(fileName, file, base64);

          const xhr = new XMLHttpRequest();
          xhr.open('POST', apiUrl + '/templates/' + templateId + '/media');

          xhr.onload = () => {
            if (xhr.status !== 200) {
              alert('HTTP Error: ' + xhr.status);
              return;
            }
            const json = JSON.parse(xhr.responseText);

            if (!json || typeof json.location !== 'string') {
              alert('Invalid JSON: ' + xhr.responseText);
              return;
            }
            cb(json.location, { title: file.name });
          };

          const formData = new FormData();
          formData.append('file', blobInfo.blob(), blobInfo.filename());

          xhr.send(formData);

        };
        reader.readAsDataURL(file);
      };
      input.click();
    },

在选择上载文件并单击打开时,Chrome控制台抛出此错误:

未捕获的类型错误:无法读取未定义的属性“0”

【问题讨论】:

  • 只需添加条件检查if( this.files && this.files.length > 0 ) { // do something with this.files } 。这同样适用于其他变量
  • 还将箭头函数替换为普通的 JavaScript 函数,例如 input.onchange = () => { },因为如果你使用箭头函数,this 的值将会改变
  • @JoelJoseph 这什么也没做,因为它永远不会通过该语句。请参阅我的回答,文件被视为我的组件的一部分,而不是输入对象。因此,如果我只把那个检查放在那里,文件将永远是未定义的
  • 我知道,我在第二条评论中也提到过

标签: angular typescript upload tinymce


【解决方案1】:

文件[] 没有被初始化,这就是你未定义的原因。如果 files[] 是从 API 响应初始化的,也许您应该检查响应。你说你的后端发生了什么事。在调试模式下跟踪 files[] 变量你会发现问题。

【讨论】:

  • files 变量来自 tinyMCE 本身,它与我的后端无关。在reader.onload() 中是我的api 被使用的地方。但它的代码甚至没有到达那里。 this.files 应该在 tinymce 创建的对象中。
【解决方案2】:

我发现了问题:input.onChange 函数不应该是匿名/lambda 函数。将 input.onChanges = () => { 更改为 input.onChanges = function() { 解决了该问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多