【问题标题】:Angular 2 D3 Event, Change Detection and ContextAngular 2 D3 事件、变更检测和上下文
【发布时间】:2016-12-16 13:51:27
【问题描述】:

我的问题:我在 Angular 2 组件中使用 D3 在屏幕上绘制 SVG。这工作正常,但是我想将事件附加到 D3 生成的 SVG 并在该事件中调用我的 Angular 2 组件中的方法。该方法将获取 D3 SVG 提供的数据并将其分配给我的 Angular 2 父组件中的变量。该变量是我的 Child Angular 2 组件的输入变量。我目前无法从 D3 事件回调中调用 Angular 2 组件中的函数。关键字“this”在回调中的上下文与在 Angular 2 组件中使用它时的上下文不同,因此我无法获得能够调用我想要的函数的引用。

我的项目:所以我有一个 Angular 2 项目,我有 2 个具有父子关系的组件。 D3 Canvas 组件是父组件,正如您在下面看到的,我在此组件模板中包含一个数据详细信息面板。 data-detail-component 由输入变量“activeEntity”提供支持,我希望在 SVG 悬停时根据 D3 事件填充该变量。

<div class="row">
    <div class="col-xs-8 col-sm-8 col-md-8 col-lg-8">
        <div id="d3-canvas-host"></div>
    </div>
    <div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">
        <data-detail-panel [activeEntity]="activeEntity"></data-detail-panel>
    </div>
</div>

现在在初始化 D3 Graph 并可视化数据的 Angular 2 组件中,它是这样设置的:

import {
  Component,
  OnInit,
} from '@angular/core';
import {
  DataDetailPanel
} from '../detailPanel';

import * as D3 from 'd3';

@Component({
  template: require('./entitiesVisualisation.html'),
  styles: [require('./entitiesVisualisation.css')],
  directives: [DataDetailPanel],
})
export class EntitiesVisualisation  {
  activeEntity: any;


  drawTopologyView(nodeContainer, entityData, colorRange: D3.scale.Linear < string, string > ) {

    // Make sure that previous elements are cleared before redrawing
    nodeContainer.selectAll('*').remove();
    // Start adding Nodes to D3 Graphs
    let entityNodes: D3.Selection < any > = nodeContainer
      .attr('transform', 'translate(5,0)')
      .attr('stroke-width', '3')
      .attr('stroke', 'white')
      .selectAll()
      .data(sortedEntities)
      .enter();

    // Add new node
    entityNodes
      .append('g')   
      .attr('transform', function(d) {
        return "translate(" + d.x + "," + d.y + ")";   // Set node position from packing algorithm
      }) 
      // Add event to each node
      .on('mouseover',function (data) {
          // If node is ever hovered on then call function to change the current active entity data and pass that D3 SVGs data to that function
          this.changeActiveEntity(data); // This call doesn't work because 'this' has the SVG element as it's context not the Angular 2 component 
      } )
      .on('mouseout', function(data) {
        // D3 Svg is no longer "active" (Hovered) and so I want to update the active entity data to empty object
        this.removeActiveEntity(); // This call doesn't work because 'this' has the SVG element as it's context not the Angular 2 component
      })
      .append('circle');

  }
  changeActiveEntity(newActiveEntity){
    this.activeEntity = newActiveEntity;
  }
  removeActiveEntity(){
    this.activeEntity = {};
  }
}

【问题讨论】:

    标签: javascript d3.js angular


    【解决方案1】:

    您可以使用箭头函数来利用词法 this:

    .on('mouseout', (data) => { // <----
      // "this" corresponds now to the component instance
      this.removeActiveEntity();
    })
    .on('mouseout', (data) => { // <----
      // "this" corresponds now to the component instance
        this.removeActiveEntity();
    })
    

    查看此链接了解更多详情:

    【讨论】:

    • 以前用过词法,但只是从教程中盲目复制。从来没有真正理解它们和匿名函数之间的区别。我今天学到了一些东西!
    猜你喜欢
    • 2017-09-28
    • 2020-01-05
    • 2017-05-25
    • 1970-01-01
    • 2017-11-11
    • 2017-02-09
    • 2019-01-22
    • 2016-05-29
    • 1970-01-01
    相关资源
    最近更新 更多