不同指令中具有相同名称的函数会相互覆盖

时间:2016-09-20 16:32:32

标签: javascript angularjs

我有一个Angular.js指令,可以呈现一些D3图表:

angular.module('my-app.deltaChart', [])
.directive('deltaChart',
[ function() {
    return {
        restrict : 'E',
        scope : {
            data : '='
        },
        link : function(scope, element) {

            var container = element[0];
            var svg = d3.select(container)
                .append("svg");

            var render = function(data) {

                if (!data) {
                    return;
                }

                var bars = svg.selectAll("g");
                /**
                   etc...
                **/

            }

            scope.$watch("data", function(newData) {
                render(newData);
            }, true);

            render(scope.data);

 }}}]);

我在代码中不止一次使用此指令:

<div class="col-md-4">
  <delta-chart data="currentData.values"></delta-chart>
</div>
<div class="col-md-4">
  <delta-chart data="pastData.values"></delta-chart>
</div>

DOM中的用户操作可以通过ng-click函数更改currentData.values和pastData.values的内容。但是,只有DOM中指定的最后一个图表会更新以反映新数据;其他render函数不会被调用。

我最终跟踪了这个奇怪的行为,直到render函数表现得像一个全局变量。我的印象是,在指令的link函数中声明的任何变量都是本地范围的,并且在声明指令的任何时候都会实例化。但是,render函数似乎表现得像一个全局变量。将它绑定到指令的scope解决了问题:

        scope.render = function(data) {
                 ...
        }

        scope.$watch("data", function(newData) {
            scope.render(newData);
        }, true);

即使使用两种不同类型的指令(D3中的渲染图表),这也证明了这一点:

<div class="col-md-4">
  <delta-chart data="currentData.values"></delta-chart>
</div>
<div class="col-md-4">
  <ring-chart data="otherData.values"></ring-chart>
</div>

如果两者都有一个名为render的函数,则只会在变量更新时调用最后声明的函数。

任何人都可以帮我理解Angular.js指令中的变量范围吗?

0 个答案:

没有答案