0

如何在子组件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;
4

1 回答 1

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/

于 2017-06-04T23:22:15.557 回答