0

我有一个基于 D3 和 JS 的地球地球仪工作演示。现在我正在尝试从中创建一个 Angular 6 组件。

这是没有 Angular 的完整演示:

import * as d3 from 'd3v4';

import { Component, AfterContentInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'earth-globe',
  templateUrl: './earth-globe.component.html',
  styleUrls: ['./earth-globe.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class EarthGlobeComponent implements AfterContentInit {
  private canvas;
  getCountry(c) {
    console.log('Country is: ', c);
  }

  mousemove() {
    console.log('mousemove()::this==', this); // now 'this' points to canvas, which is CORRECT
    // console.log('globe==', globe);
    console.log('ev==', event); // but I also need event
    const c = this.getCountry(this); // and acces to this.getCountry
  }


  ngAfterContentInit() {
    this.canvas = d3.select('#globe');
    this.canvas
      .on('mousemove', this.mousemove)
  }
}

http://jsfiddle.net/up715k2n/

这是简化的 Angular 组件演示:

https://stackblitz.com/edit/angular-dohwvt

如果您移动鼠标,应用程序将 console.log 'this'。在两个演示中,我都有指向画布的“this”,这是正确的。

但在 Angular 示例中,该应用程序有一个错误:

this.getCountry 不是函数

因为 'getCountry' 是一个组件方法,而不是画布。

所以,我试图找到同时获取上下文的方法 - 画布和组件。

怎么做?

https://stackblitz.com/edit/angular-rlttwv?file=src/app/earth-globe.component.ts - 指向组件

https://stackblitz.com/edit/angular-xjahkl?file=src/app/earth-globe.component.ts - 指向画布

4

1 回答 1

0

您可以使用下一个语法(它不是标准的一部分,但支持 babel )

  // instead of mouse() {
  mousemove = () => {
    console.log('mousemove()::canvas==', this.canvas); // <-- canvas
    console.log('component==', this); // <-- component
    console.log('ev==', event);
    const c = this.getCountry(this);
  }

它将绑定方法内的上下文

旧式修复而不是这样

  ngAfterContentInit() {
    this.canvas = d3.select('#globe');
    this.canvas
      .on('mousemove', this.mousemove.bind(this)) // <-- changes is .bind(this)
  }

https://javascriptweblog.wordpress.com/2015/11/02/of-classes-and-arrow-functions-a-cautionary-tale/

于 2018-09-24T18:41:05.243 回答