【问题标题】:Unable to access 'this' context in addEventListener() in Angular 2 component无法在 Angular 2 组件的 addEventListener() 中访问“this”上下文
【发布时间】:2018-08-05 19:04:54
【问题描述】:

无法在角度 2 中访问 addEventListener() 中的“this”上下文

在我的富文本编辑器组件中,我正在实现图像上传功能。 为此,我为图像输入标签中的“更改”编写了一个 addEventListener 事件处理程序,我需要通过“this”访问事件侦听器内的应用服务。

    Imageinput.addEventListener('change', () => {
                const file = Imageinput.files[0];
                var a = this;           

                if (Imageinput.files != null && Imageinput.files[0] != null) {
                    debugger;     
                    this._imageUploadService.uploadImageToBlob(file).subscribe((res) => {
                        debugger;
                        this._returnedURL = res.imageUrl;
                        this.pushImageToEditor();
                    });               
                }
            }
            );

但是 this._imageUploadService 每次都返回 undefined,即使控制台没有任何错误。


Here is my complete component.ts code -
    export class CreateArticleComponent extends AppComponentBase {

        @ViewChild("fileInput") fileInput;

        public editor;
        public _returnedURL = "";    

        constructor(
            injector: Injector,
            private _imageUploadService: ArticleServiceProxy,
        ) {
            super(injector);
        }

        onEditorBlured(quill) {
            console.log('editor blur!', quill);
        }

        onEditorFocused(quill) {
            console.log('editor focus!', quill);
        }

        onEditorCreated(quill) {
            console.log(quill);
            let toolbar = quill.getModule('toolbar');
            toolbar.addHandler('image', this.imageHandler);        

            //this.editorContent = quill;
            this.editor = quill;
            console.log('quill is ready! this is current quill instance object', quill);
        }

        imageHandler() {           
            debugger;
            let self = this;

            const Imageinput = document.createElement('input');
            Imageinput.setAttribute('type', 'file');
            //Imageinput.setAttribute('name', 'articleImage');
            Imageinput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
            Imageinput.classList.add('ql-image');


            Imageinput.addEventListener('change', () => {
                const file = Imageinput.files[0];

                if (Imageinput.files != null && Imageinput.files[0] != null) {
                    debugger;
this._imageUploadService.uploadImageToBlob(file).subscribe((res) => {
                        debugger;
                        this._returnedURL = res.imageUrl;
                        this.pushImageToEditor();
                    });                   
                }
            }
            );

            Imageinput.click();
        }

        SendFileToServer(file: any) {
            debugger;
            this._imageUploadService.uploadImageToBlob(file).subscribe((res) => {
                debugger;
                this._returnedURL = res.imageUrl;
                this.pushImageToEditor();
            });
        }

        pushImageToEditor() {
            debugger;
            const range = this.editor.getSelection(true);
            const index = range.index + range.length;
            this.editor.insertEmbed(range.index, 'image', this._returnedURL);
        }

        ngAfterViewInit() {           
        }
    }    

Here is my editor HTML -

  <quill-editor #fileInput                                  
            [(ngModel)]="editorContent"
            [ngModelOptions]="{standalone: true}"
            (onEditorCreated)="onEditorCreated($event)"
            (onContentChanged)="onContentChanged($event)"
            (onSelectionChanged)="logSelection($event)"
            [style]="{'height':'300px'}">
</quill-editor>

我可以通过其他方法访问this._imageUploadService,但无法在 addEventListener() 中访问它。任何帮助将不胜感激

【问题讨论】:

  • 您对this 的期望是什么?由于您使用的是箭头函数,因此内部和 addEventListener 回调都是相同的。
  • 你在不使用调试器的时候真的有什么错误吗?如果不是,可能不是调试器与范围混淆了,我有时会遇到这种情况
  • 您可以使用 angular Renderer2 在事件侦听器中使用类的上下文,这也是创建 Input 元素的首选方式。

标签: javascript angular angular2-services image-upload quill


【解决方案1】:

in change 事件处理程序this 指的是toolbar.addHandler 的上下文,所以你需要它像这样绑定this.imageHandler

  onEditorCreated(quill) {
        console.log(quill);
        let toolbar = quill.getModule('toolbar');
        toolbar.addHandler('image', this.imageHandler.bind(this));  // <--      

        //this.editorContent = quill;
        this.editor = quill;
        console.log('quill is ready! this is current quill instance object', quill);
    }

【讨论】:

  • 谢谢哥们,你是对的。我试图找到一种使用 .bind(this) 的方法,但没有找到方法。现在“this”也可以在事件监听器中访问.我浪费了 2 天的时间来寻找解决方案。 #再次感谢
【解决方案2】:

您可以简单地使用 Angular Renderer2 包装器,而不是使用 .bind 或尝试强制对象/上下文进入回调,这将使您能够访问组件类上下文。

    imageHandler() {
    debugger;

    const Imageinput = this.renderer.createElement('input');
    this.renderer.setAttribute(Imageinput, 'type', 'file');
    this.renderer.setAttribute(Imageinput, 'accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
    this.renderer.addClass(Imageinput, 'ql-image');

    this.renderer.listen(Imageinput, 'change', () => {
      if (Imageinput.files != null && Imageinput.files[0] != null) {
        debugger;
        this._imageUploadService.uploadImageToBlob(file).subscribe((res) => {
          debugger;
          this._returnedURL = res.imageUrl;
          this.pushImageToEditor();
        });
      }
    });

    Imageinput.click();
  }

【讨论】:

  • 这也是使用angular渲染器的正确方法。但是我是angular 2的新手,所以我不知道使用它。我一定会尝试并通知你。 #谢谢丹尼尔
  • 不客气,总是尽量远离文档和窗口对象,因为一旦你想去通用应用程序它的阻塞。不客气。我已经测试了它应该可以工作的大部分代码。
猜你喜欢
  • 2015-08-07
  • 2018-01-31
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2016-12-10
  • 2017-11-26
  • 1970-01-01
  • 2019-03-31
相关资源
最近更新 更多