我使用HighCharts代表堆积条形图以及折线图。我的要求是 onClick 堆积条形图折线图应该显示对应于点击的部分。我使用 $ broadcast 和 $ on 来实现它。当我在 highchart.js 中使用 $ emit 时,它无效,但是当我使用 $ broadcast 或 $ scope时。$ parent 。$ broadcast 它有效。有人可以让我知道为什么事件的向上流动正在发挥作用,向下流动它不起作用。我的两个指令都是针对同一个控制器。
在我的情况下,为什么 $ scope。$ emit 或 $ scope。$ broadcast 单独工作?
index.html
<div ng-controller='MainCtrl'>
<chart values='basicAreaChart' id="container" technology="3G" url="../json/HighCharts.json"></chart>
<linechart values='basicLineChart' id="container2" technology="LTE" click='clicked'></linechart>
</div>
controller.js
angular.module('chartsExample', ['lineChart','highchart']).controller('MainCtrl',
[ '$scope', '$http', function($scope, $http) {
} ]);
highchart.js
'use strict';
angular.module('highchart', []).directive('chart', function() {
return {
restrict: 'E',
scope: {
chartData: "=values"
},
transclude: true,
replace: true,
controller:function($scope,$element,$attrs,$http){
$http.get($attrs.url).success(function(data) {
$scope.chartData = data;
console.log('technology='+$attrs.technology+' '+$scope.a);
});
},
link: function($scope, $element, $attrs,$rootScope) {
'+$attrs.type);
$scope.$watch('chartData', function(value) {
if (!value){
//console.log('In return');
return;
}
// Initiate the chartData.chart if it doesn't exist yet
$scope.chartData.chart = $scope.chartData.chart ;
$scope.chartData.chart.renderTo =$attrs.id
$scope.chartData.chart.events = {
click : function() {
console.log('Chart clicked '+$scope.isClicked+' '+$scope.a);
$scope.click="false";
$scope.$parent.$broadcast('HIGH_CHART_CLICKED', 'clicked');
//This works but $scope.$emit or $scope.$broadcast does'nt work???
}
};
$scope.chartObj = new Highcharts.Chart($scope.chartData);
},true);
}
};
});
linechart.js
'use strict';
angular.module('highchart', []).directive('chart', function() {
return {
restrict: 'E',
scope: {
linechartData : "=values"
},
transclude: true,
replace: true,
controller:function($scope,$element,$attrs,$http){
$scope.$on('HIGH_CHART_CLICKED',function(e,data){
console.log('Line chart Listening event');
$http.get("../json/NewLineChart.json").success(function(data) {
$scope.linechartData = data;
console.log('this is from line chart');
});
});
},
link: function($scope, $element, $attrs,$rootScope) {
'+$attrs.type);
$scope.$watch('linechartData', function(value) {
if (!value){
//console.log('In return');
return;
}
// Initiate the chartData.chart if it doesn't exist yet
$scope.chartData.chart = $scope.chartData.chart ;
$scope.chartData.chart.renderTo =$attrs.id
}
};
$scope.chartObj = new Highcharts.Chart($scope.chartData);
},true);
}
};
});
答案 0 :(得分:3)
确定。您有两个具有相同名称的指令(图表)。这个答案假设第二个实际上应该是线图
图表和折线图是兄弟姐妹。所以当你从图表广播一个事件时,它没有孩子,也没有人听到它。
同样,如果您从图表中发出$ emit和event,那么它将被发送到父作用域(MainCtrl),然后在层次结构上向$ rootScope发出。它永远不会到达线图
当你使用$ scope。$ parent。$ broadcast时,你告诉MainCtrl将事件广播给它的孩子,这恰好是图表和线图,所以它可以工作。
长话短说 - 角度正如预期的那样工作。
与浏览器事件不同,角度事件不会向下冒泡然后再进行备份。他们是单向的。
您可以让MainCtrl侦听该事件,然后重新广播它:
在MainCtrl中:
$scope.$on('HIGH_CHART....', function() {
//rebroadcast to children
var args = Array.prototype.shift.apply(arguments);
$scope.$broadcast('HIGH_CHART.....', args )
};
(或类似的东西。你必须从参数中删除第一个元素,然后用剩余的参数调用广播 - 超出问题的范围)。