Избегайте нацеливания области видимости этого объекта внутри функции в ES6

Например, я запускаю проект с D3.js, импортирую определенные модули и вызываю их функции.

Настройка:

  • Машинопись /ES6
  • Импорт определенных компонентов D3
  • Угловой 6

У меня есть объект, в данном случае угловая директива, и я рисую несколько кругов на холсте SVG и хочу, чтобы они вызывали функцию при событии перетаскивания.

Сокращенный фрагмент кода: Пожалуйста, посмотрите drawPoints() внизу этого фрагмента.

import { ElementRef, HostListener, Output, EventEmitter, OnInit, Input, OnChanges, SimpleChanges, Directive } from '@angular/core';
import * as Selection from 'd3-selection';
import * as Shape from 'd3-shape';
import * as Random from 'd3-random';
import * as Drag from 'd3-drag';

import { Config } from './../models/config.model';
import { Point } from './../models/point.model';
import { Param } from './../models/param.model';

@Directive({
  selector: '[appCanvas]'
})
export class CanvasDirective implements OnInit, OnChanges {
  private canvas: any;
  private defs: any;
  private gradient: any;
  private svg: any;
  private expandedPoints: Point[];
  private drag: Point;
  public config: Config;

  @Input()
  private param: Param;

  @Output()
  private emitConfig: EventEmitter<Config>;

  @HostListener('window:resize', ['$event'])
  private onResize(event) {
    this.init();
  }

  constructor(
    private el: ElementRef
  ) {
    this.canvas = el.nativeElement;
    this.emitConfig = new EventEmitter();
  }

  ngOnInit() {
    intSvg();
    // ..
  }

  private initSvg() {
    if (!this.svg) {
      this.svg = Selection.select(this.canvas).append('svg');
    }
    this.svg
      .attr('width', this.config.width)
      .attr('height', this.config.height);
  }

  private drawPoints(points: Point[]) {
    points.forEach(point => {
      this.svg.append('circle')
        .attr('r', point.color ? 20 : 10)
        .attr('cx', point.x)
        .attr('cy', point.y)
        .attr('fill', point.color ? point.color : 'lightgray')
        .attr('stroke-width', !point.color ? 2 : 0)
        .attr('stroke', !point.color ? 'gray' : '')
        .call(Drag.drag()
          .on('drag', () => {
            // What to call here?
            // Selection.select(this) will not work
            // So how to target the correct „this“?
          }));
    });
  }
  // ...
}

Возникающая проблема заключается в невозможности достичь правильного значения this внутри функции перетаскивания добавленных кругов.

Есть несколько примеров, но они не будут работать внутри класса, потому что аргумент this защищен.

Кредиты на примере Майка Бостока

4 голоса | спросил Michael Czechowski 13 Maypm18 2018, 22:23:00

2 ответа


0
Старые библиотеки, такие как D3, используют динамический контекст ---- +: = 0 =: + ---- вместо передачи всех необходимых данных в качестве аргументов и требуют использования ---- +: = 1 =: + ----хитрость для достижения лексического ---- +: = 2 =: + ---- в обратных вызовах.Трюк считается устаревшим в ES6, но в таких случаях это необходимо.Обычная функция должна использоваться вместо стрелки, чтобы получить динамический контекст:Может показаться непоследовательным, что экземпляр класса должен называться ---- +: = 4 =: + ---- в одних местах и ---- +: = 5 =: + ---- в других (этоне было проблем в ES5, потому что ---- +: = 6 =: + ---- должен был быть тщательно использован в таких случаях для согласованности).Как объяснено в этом связанном ответе , альтернативой является функция-обертка, которая будет предоставлять контекст функции D3 обратного вызова в качестве параметра, в то время как ---- +: = 7 =: + ---- может по-прежнему ссылаться на экземпляр класса.Функции стрелок могут использоваться в этом случае:
ответил estus 13 Maypm18 2018, 23:11:27
0
Избегая популярного синтаксиса функции стрелки в компонентах ES6 и использовав вместо этого старый добрый синтаксис ---- +: = 0 =: + ---- , проблема была решена.Функции со стрелками меняют игру, потому что внутри этих вызываемых функций оказывается, что ---- +: = 1 =: + ---- не сводится к вызываемому контексту функции, но контекст распространяется глобально доуровень класса.Решение:Дальнейшее чтение:[...] и ES2015 [ES6] представили функции стрелок, которые не предоставляют свои привязки this (он сохраняет значение this лексического контекста).Rwaldron, abasao, martian2049 et.Аль, это , MDN веб-документы
ответил Michael Czechowski 13 Maypm18 2018, 22:24:34

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132