角度服务回调命令组合

时间:2018-03-14 22:30:31

标签: angular typescript

设置

我一直致力于创建一个API,用于创建适用于任何给定Angular组件的动态键盘快捷键。以下是用于表示Shortcut的模型:

export class Shortcut {
  keyCode: number;
  command: Function;
  args?: any;

  constructor(keyCode: number, command: Function, args?: any[]) {
    this.keyCode = keyCode;
    this.command = command;
    if (args) {
      this.args = args;
    }
  }
}

预期用途如下:

// function called in component OnInit function
initializeShortcuts() {
    this.shortcutService
        .addShortcut(
            KeyCodes.One, 
            this.md.createMarkdown, 
            [this.mdEditor, '#']
         );      
}

在组件模板中,针对textarea检查keydown事件,而textarea又调用checkShortcut上的ShortcutService函数。这是整个服务:

import { Injectable } from '@angular/core';
import { Shortcut } from './shortcut';


@Injectable()
export class ShortcutService {
  shortcuts = new Array<Shortcut>();

  checkShortcut(event: KeyboardEvent) {
    if (event.ctrlKey) {
      const result = this.shortcuts.filter((s: Shortcut) => {
        return s.keyCode === event.keyCode;
      })[0];

      if (result) {
        console.log(result);
        event.preventDefault();
        result.args ? result.command(...result.args) : result.command();
      }
    }
  }

  addShortcut(keyCode: number, command: Function, args?: any[]) {
    this.shortcuts.push(new Shortcut(keyCode, command, args));
  }

  removeShortcut(shortcut: Shortcut) {
    const index = this.shortcuts.indexOf(shortcut);
    this.shortcuts.splice(index, 1);
  }
}

问题

正如我现在所做的那样,它有效,但我必须在回调函数本身中明确定义任何支持函数,因为this上下文不可用,如MarkdownService中所示:

createMarkdown(editor: ElementRef, markdown: string) {
    function getEditorValues(editor: ElementRef): EditorValues {
      return new EditorValues(
        editor.nativeElement.selectionStart,
        editor.nativeElement.selectionEnd,
        editor.nativeElement.value.length,
        editor.nativeElement.value
      );
    }

    const values = getEditorValues(editor);

    if (values.start === values.end) {
      editor.nativeElement.value = `${values.zeroToStart}${markdown}${values.startToLength}`;
    } else {
      editor.nativeElement.value =  `${values.zeroToStart}${markdown}${values.startToLength}`;
    }
}  

如果我在服务本身中定义getEditorValues()并在分配values常量时引用该函数调用,则会抛出错误,因为该对象未定义。

有没有更好的方法来完成这样的事情,其中​​可以在回调函数之外访问依赖功能?

例如,请参阅StackBlitz Project

1 个答案:

答案 0 :(得分:1)

您可以通过使用箭头函数包装函数来保留函数的this上下文。而不是传递这个:

this.md.createMarkdown

传递以下内容:

(...params) => this.md.createMarkdown(...params)

或者您可以通过传递以下内容来绑定this

this.md.createMarkdown.bind(this)