事件多次调用

时间:2016-07-20 06:41:50

标签: javascript angularjs

在融合图表中,一旦我点击图例然后如果我点击钻取点意味着点击事件多次调用,因为这个多重钻取弹出窗口显示...

指令

angular
  .module("rootApp")
  .directive('fchart', function(chartExportService, $timeout, $uibModal, chartDrillDownService, appNotifyService) {
      return {
        restrict: "E",
        scope: {
          cid: '@',
          dataformat: '@',
          width: '@',
          height: '@',
          dataSource: '@',
          type: '@',
          charts: '=',
          control: '=',
          data: '@'
        },
        link: function(scope, element, attrs) {
          scope.internalControl = scope.control || {};

          var chart = null;
          var exportList = [];
          var agentData = {};
          scope.actionAfterExport = 'print';

          var chartConfigObject = {
            type: scope.type,
            width: scope.width,
            height: scope.height,
            renderAt: element[0],
            id: scope.cid,
            dataFormat: scope.dataformat || 'json',
            dataSource: attrs.datasource,
            events: {
              "beforeExport": function(evtObj, argObj) {
                var exportStatus = document.getElementById('chart-export-status');
                if (exportStatus) {
                  exportStatus.style.display = 'inline';
                }
              },
              "exported": function(eventObj, dataObj) {
                var exportStatus = document.getElementById('chart-export-status');
                if (exportStatus) {
                  exportStatus.style.display = 'none';
                }
              },
              "dataplotclick": function(ev, props) {


              }
            }
          };

          // Register methods for chart drill down calls from fusion chart
          // As fusion chart look for those methods in window scope, these
          // functions needs to be registered in window scope

          window.chartDrillDown = function(info) {
            chartDrillDownService.doDrillDown('chartDrillDown', info);
          };

          window.popupforTop10StnAndFisPCharts = function(info) {
            var test = true;
            if (test) {
              chartDrillDownService.doDrillDownFisPChart('popupforTop10StnAndFisPCharts', info);
            }
            test = false;
          };

          window.activityCountJs = function(info) {
            chartDrillDownService.doDrillDown('activityCountJs', info);
          };

          window.chartPopUpForTop10ByStationCharts = function(info) {

            chartDrillDownService.doDrillDownFisPChart('chartPopUpForTop10ByStationCharts', info);
          };

          window.chartDrillDownForLabels = function(info) {
            chartDrillDownService.doTreeDrillDown('chartDrillDownForLabels', info);
          };

          window.Reveal = {};
          window.Reveal.PlantView = {
            DrillHandler: {}
          };
          window.Reveal.Compare = {
            DrillHandler: {}
          };

          window.Reveal.PlantView.DrillHandler.PopupActivity = function(info) {
            chartDrillDownService.doDrillDown('PlantView-PopupActivity', info);
          };

          window.Reveal.PlantView.DrillHandler.DrillActivity = function(info) {
            chartDrillDownService.doDrillDown('PlantView-DrillActivity', info);
          };

          window.Reveal.Compare.DrillHandler.DrillHours = function(info) {
            chartDrillDownService.doDrillHours('Compare-DrillHours', info);
          };

          window.Reveal.Compare.DrillHandler.DrillWeekly = function(info) {
            chartDrillDownService.doDrillWeekly('Compare-DrillWeekly', info);
          };

          window.Reveal.Compare.DrillHandler.DrillDay = function(info) {
            chartDrillDownService.doDrillDay('Compare-DrillDay', info);
          };

          var createFCChart = function() {
            // dispose if previous chart exists
            if (chart && chart.dispose) {
              chart.dispose();
            }

            // Setting to make FusionCharts rendering properly when <base> tag included in HTML head 
            FusionCharts.options.SVGDefinitionURL = 'absolute';

            chart = new FusionCharts(chartConfigObject);

            /* @todo validate the ready function whether it can be replaced in a better way */
            angular.element(document).ready(function() {
              element.ready(function() {
                // Render the chart only when angular is done compiling the element and DOM.
                chart.showBorder = 0;
                chart = chart.render();
                chart.uniqueId = scope.data || null;

                if (scope.charts) {
                  scope.charts.push(chart);
                }
              });
            });
          };
        };

任何指针都将不胜感激!

3 个答案:

答案 0 :(得分:0)

事件可能会被DOM层次结构中的多个目标调用。通过使用console.log来确定事件的当前目标来验证这一点。 Reference

如果是这种情况,那么停止此操作的一种方法是在事件上调用stopPropagation()。 Reference

可以取消注释评论的行以测试您的情况:

"beforeExport": function(evtObj, argObj) {
// console.log(evtObj.currentTarget);
var exportStatus = document.getElementById('chart-export-status');
if (exportStatus) {
    exportStatus.style.display = 'inline';
}
//evtObj.stopPropagation();

}

答案 1 :(得分:0)

这可能对您的问题有所帮助。

Event.stopPropagation()

阅读文档here

答案 2 :(得分:0)

简短回答

选项1

创建另一个$scope变量,用于存储图例可见性的状态。类似于CSS Checkbox Hack的东西。然后使用ng-ifng-showng-hide指令根据$scope变量的值显示/隐藏预制DOM元素。

选项2

无论生成drilldown popup的代码是什么,都要从angular指令/表达式中删除它并将其放在外部函数中。有这个功能检查它是否最近显示了一个弹出窗口,

  • 如果有:不显示弹出窗口
  • 如果没有:确实显示弹出窗口

解释

我也注意到了这种行为。它是由角度引擎通过DOM寻找需要评估的表达式进行多次传递引起的。 我完全不知道,但这些阶段可能是这样的:

  1. 深度搜索:识别所有存在的表达式并标记它们
  2. evaluate:遍历标志并实际评估表达式
  3. 如果你的表达式在ng-repeat块内,那么这种效果会比没有表达效果大得多。

    我找到了一个解释得非常好的来源:sitepoint.com。 这种影响是由脏形式的数据检查引起的。 Angular运行DOM评估表达式并执行操作。然后,它再次运行它以确保所有数据都正确绑定。如果数据仍然没有达到速度(可能你的一个函数改变了一个值),那么它将继续通过DOM直到所有内容都同步。

    免责声明:我没有使用过Fusion Charts。 但是,我仍然有很多代码经验,我建议移动任何生成模态框的代码(进入一个可以使用更复杂的逻辑来检查是否实际运行的函数)。

    在我对模态的看法中,你不应该在Angular表达式中生成弹出框。模态应该用于显示基准步骤(如错误或成功)。