我有以下指令:
app.directive('rickshawChart', function()
{
return{
$scope: {
data: '=',
renderer: '='
},
template: '<div></div>',
restrict: 'E',
link: function postLink(scope, element, attrs)
{
scope.$watchCollection('[data,renderer]', function(newVal, oldVal)
{
if(!newVal[0])
{
return;
}
var graphEl = element.find("div:first");
graphEl.html('');
var graph = new Rickshaw.Graph({
element: graphEl[0],
width: attrs.width,
height: attrs.height,
series: [{data: scope.data, color: attrs.color, name: attrs.series}],
renderer: scope.renderer
});
graph.render();
});
}
}
});
使用以下 html:
<rickshaw-chart
data="sightingByDate"
color="green"
renderer="renderer"
width="100%"
height="100%">
</rickshaw-chart>
这里我用下面的 Controller 填充数据:
app.controller('CompetenceController', ['$http', '$scope','$sessionStorage','$log','Session','api', function ($http, $scope, $sessionStorage,$log, Session, api) {
$scope.result =[ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ];
$scope.renderer = 'scatterplot';
$scope.sightingsByDate = _($scope.result)
.chain()
.countBy(function(sighting){
return sighting.y;
})
.pairs()
.map(function(pair){
return pair;
})
.value();
}]);
但是从调试器中我可以看到 $watchCollection
从未被执行。
我做错了什么?
最佳答案
您应该使用带有 true
作为第三个参数的 $watch
表达式:
scope.$watch('[data,renderer]', function (newVal, oldVal) {
//code
}, true);
$watchCollection
对您不起作用,因为您同时拥有数组和属性。在这种情况下,就像您正在同时检查 $scope.$watch('data'
和 $scope.$watch('renderer'
。如果数组改变,事件不会触发。
$watch
有四种类型:
- 最简单的是
$watch
,它只是检查属性或整个对象是否发生了变化 - 第二个是
$watchCollection
,它监视数组中的任何属性是否发生更改(在您的情况下这不起作用,因为您同时拥有数组和属性) - 第三个是
$watchGroup
(自 1.3 起),它是$watchCollection
的最新版本,它允许您检查表达式数组(但同样可以像您尝试的那样通过$watchCollection
实现 $watch('object', function(){...}, true)
。这会检查对象中的每个属性是否都发生了变化
这是您的代码的简化版本,如果您按下更改值按钮,您可以看到数组中的元素是如何更改的以及事件是如何在控制台中触发的: http://jsfiddle.net/27gc71bL/
编辑:我忘记在我的回答中添加一些内容。 我认为您的代码中有错字,您正在使用以下命令创建指令:
$scope: {
data: '=',
renderer: '='
},
这不是在指令中创建新的范围。因此,当您在链接函数中使用 scope.data
时,您指的是父级( Controller )的 $scope.data
。
我想你想要的是以这种方式创建一个新的范围:
scope: {
data: '=',
renderer: '='
},
然后,在您的 Controller 中,将您要检查的数组绑定(bind)到 sightingByDate
。
关于javascript - $watchCollection 未被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29409338/