简体   繁体   English

在控制器中调用Angular函数并将结果传递给指令

[英]Call Angular function in controller and pass result to directive

I am having a problem with Angular's digest cycle going crazy: 我在Angular的摘要周期变得疯狂时遇到问题:

angular.js:12330 Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

I have this custom Directive: 我有这个自定义指令:

<b-bar-chart b-data="getData(question)"></b-bar-chart>

in Which, the getData function calls a function in the controller (NOT IN THE DIRECTIVE so using & instead of = in the directive for one way binding does not work). 其中,getData函数在控制器中调用一个函数(不在指令中,因此在指令中使用&而不是=以一种方式进行绑定无效)。 Controller function: 控制器功能:

$scope.getData = function (question) {
    return [
      {
        'name': 'Strongly Agree',
        'value': question.stats.responsePercentages.stronglyagree
      },
      {
        'name': 'Agree',
        'value': question.stats.responsePercentages.agree
      }
    ]
  }

In the Directive I have this: 在指令中,我有以下内容:

scope: {
    // I think this should this be = and not &, because the function is in the controller and not in the directive
    data: '=bData'
},

And in the directive template I have this: 在指令模板中,我有这个:

<li ng-repeat="d in data">
    <div class="percent">{{d.value|number:0}}<span>%</span></div>
    <div class="fm-bar-text">{{d.name}}</div>
</li>

It looks like it continues to call the code in the controller which causes unnecessary loops. 看起来它继续在控制器中调用代码,这导致不必要的循环。 Is there a way to make sure the getData function is called only once, or is there a different solution? 有没有办法确保getData函数仅被调用一次,或者有其他解决方案? Thanks 谢谢

getData should not return a new array, otherwise Angular assumes the data is new. getData不应返回新的数组,否则Angular会假定数据是新的。 You should assign the result to $scope and bind it that way. 您应该将结果分配给$scope并以这种方式绑定。 Its generally best to avoid function calls when binding. 通常最好在绑定时避免函数调用。

Instead of computing getData(question) every digest cycle, refactor to compute it only when question changes: 与其在每个摘要循环中计算getData(question) ,不如仅在question发生变化时进行重构以计算出它:

Parent Controller: 上级主管:

 $scope.$watch("question", function(newValue) {
     $scope.bData = $scope.getData(newValue);
 });

HTML: HTML:

 <!-- Re-factor this -->
 <b-bar-chart b-data="getData(question)"></b-bar-chart>

 <!-- TO this -->
 <b-bar-chart b-data="bData"></b-bar-chart>

So instead of computing the array every digest cycle, a new array is created only when the question changes. 因此,不是在每个摘要周期都计算数组,而是仅在question更改时才创建一个新数组。

In directive = used for two way binding between scope variables. In指令=用于范围变量之间的双向绑定。 In your directive you are binding it to a function return value which will be considered as a new value every time and digest process will take place continuously. 在您的指令中,您将其绑定到函数返回值 ,该值每次都会被视为新值,摘要过程将连续进行。

I would suggest to call the function inside directive and assign it to a scope variable. 我建议调用该函数内部指令并将其分配给作用域变量。

Check out Working Fiddle . 查看工作小提琴

Directive: 指示:

MyApp.directive("bBarChart", function($compile){
    return {
      restrict: "E",
    scope: {
      data: '&bData'
    },
    template: '<li ng-repeat="d in data_values">' +
      '<div class="percent">{{d.value|number:0}}<span>%</span></div>' +
      '<div class="fm-bar-text">{{d.name}}</div>' +
        '</li>',
    link: function(s, e, a){
        s.data_values = s.data();
    }
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM