angularjs nvd3调度图事件不会触发$ onChanges()

时间:2017-06-04 21:00:30

标签: javascript angularjs angularjs-nvd3-directives

如何让angularjs nvd3 dispatch.elementMouseover在子组件中触发$onChanges()

父组件控制器(StatsComponent)

class StatsController {

  constructor( $q, PlayerService, PointService ) {
    'ngInject';
    this.$q = $q;
    this.PlayerService = PlayerService;
    this.PointService = PointService;
  }


  $onInit() {

    const P_players = this.PlayerService.getAllPlayer();
    const P_points = this.PointService.getPointLeader();

    this.pointChartOptions = this.setChartOptions();

    this.$q.all([ P_players, P_points ])
      .then(payload => {            
        this.pointLeadersVM = this.getLeadersVM(payload[0], payload[1]);
        this.selectedPointLeader = this.pointLeadersVM[0];
        this.pointData = this.getPointData(payload[1]);
        this.setPointChartMouseOver(this.pointLeadersVM);
      });
  }



  setChartOptions() {
    return {
      chart: {
        type: 'multiBarHorizontalChart',
        height: 300,
        x: function (d) { return d.label; },
        y: function (d) { return d.value; },
        duration: 500,
        multibar: {
          dispatch: {
            elementMouseover: function (e) { /* see setPointChartMouseOver method */ }
          }
        },
      }
    }
  }



  setPointChartMouseOver(pointLeaders) {
    this.pointChartOptions.chart.multibar.dispatch.elementMouseover = function(e) { this.selectedPointLeader = pointLeaders[e.index]; };
  }



  getLeadersVM(players, leaders) {
    // get leaders vm code ...
  }



  getPointData(leaders) {
    // chart data code ...
  }

}

export default StatsController;

父组件HTML(StatsComponent)

<leader selectedleader="vm.selectedPointLeader"></leader>
<nvd3 options="vm.pointChartOptions" data="vm.pointData"></nvd3>

子组件(LeaderComponent)

import controller from './leader.component.controller';
import template from './leader.component.html';
import './leader.component.styl';

const LeaderComponent = {
  bindings: {
    selectedleader: '<'
  },
  template,
  controller,
  controllerAs: 'vm'
}

export default LeaderComponent;

子组件控制器(LeaderComponent)

class LeaderComponent {

  $onChanges() {
    console.log('from child component ', this.selectedleader);
  }
}

export default LeaderComponent;

1 个答案:

答案 0 :(得分:0)

噢噢,想通了!!!

注入$scope,然后拨打$scope.$apply()。还必须使用箭头功能。

父组件控制器(StatsComponent)

class StatsController {

  constructor( $q, $scope, PlayerService, PointService ) {
    'ngInject';
    this.$q = $q;
    this.$scope = $scope;
    this.PlayerService = PlayerService;
    this.PointService = PointService;
  }

  // this.$scope.$apply(fn) passing function arg into $apply()

  setPointChartMouseOver(pointLeaders) {
    this.pointChartOptions.chart.multibar.dispatch.elementMouseover = (e) => {
      this.$scope.$apply(() => this.selectedPointLeader = pointLeaders[e.index]);
    };
  }


  // OR this.$scope.$apply() without passing function arg into $apply()


  setPointChartMouseOver(pointLeaders) {
    this.pointChartOptions.chart.multibar.dispatch.elementMouseover = (e) => {
      this.selectedPointLeader = pointLeaders[e.index];
      this.$scope.$apply();
    };
  }

关于$ apply()的文章 https://www.sitepoint.com/understanding-angulars-apply-digest/