Ng-Options Expression Repeatedly Called

回眸只為那壹抹淺笑 提交于 2019-12-31 03:22:07

问题


I am having multiple issues with my <select> element in angular and am trying to understand what is going on. My first step is to understand why the multiple console.log() messages I have put in for debugging repeatedly appear in the console, as in, instead of the message appearing once like I would expect, they appear an infinite number of times, as if part of an infinite loop. Is this how a function called from an ng-options is supposed to behave? If so, I don't understand why, if not, then I would like to fix my loop.

My html: <select ng-options="theorderdate as theorderdate for theorderdate in getOtherOrderDates(Bread.text)" ng-model="randomDateRomantic.randomDateRomantic" ng-change="soRomantic(Bread.text)"></select>

The console.log() messages appear from the getOtherOrderDates() function, which is below (with my comments included):

$scope.getOtherOrderDates = function(loaf) {
  var istheLoafdaily = false;
  var theorderdates = [];
  for (var i = 0; i < $scope.theBreadsList.length; i++) {
    for (var z = 0; z < $scope.theBreadsList[i].breads.length; z++) {
      if ($scope.theBreadsList[i].breads[z].text == loaf && i > 0) //not a daily loaf, goes beyond "Daily Breads" 
      {
        console.log(theorderdates);
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates); //concat the matched bread's order dates
        console.log(theorderdates, $scope.theBreadsList[i].breads[z].orderDates);
        theorderdates = _.sortBy(theorderdates, function(m) {
          return m.getTime()
        });
        for (var y = 0; y < theorderdates.length; y++) {
          theorderdates[y] = theorderdates[y].toLocaleDateString();
        }
        theorderdates = _.uniq(theorderdates);
        if (theorderdates.length > 0) {
          console.log("Something is wrong here"); //problem
          $scope.randomDateRomantic.randomDateRomantic = theorderdates[0];
        }
        console.log(theorderdates);
        return theorderdates;
      } else if ($scope.theBreadsList[i].breads[z].text == loaf && i == 0) { //a daily loaf, i == 0
        console.log("The bread matched is daily", loaf); //***
        istheLoafdaily = true;
        console.log(theorderdates); //***
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates); // concat the matched bread's order dates
        console.log(theorderdates, $scope.theBreadsList[i].breads[z].orderDates); //***
        break; // escape the for loop, should it be two breaks?????? yes...
      } else if (istheLoafdaily && i > 0 && $scope.theBreadsList[i].breads[z].orderDates.length > 0) { //not sure what scenario this matches, hence wtf
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates);
        console.log("wtf");
      }

    }
  }
  //end of outermost for loop
  //not sure what this is doing because this functionality is repeated up there^ (for non-daily breads)
  theorderdates = _.sortBy(theorderdates, function(m) {
    return m.getTime()
  });
  for (var y = 0; y < theorderdates.length; y++) {
    theorderdates[y] = theorderdates[y].toLocaleDateString();
  }
  theorderdates = _.uniq(theorderdates);

  if (theorderdates.length > 0) {
    $scope.randomDateRomantic.randomDateRomantic = theorderdates[0];
    console.log("Something is wrong here (daily)"); //problem
  }
  return theorderdates;
  //not sure what this is doing because this functionality is repeated up there^ (for non-daily breads)
  //if change to Locale date string then not unique, but if don't change then not a date to sort!!!!!!! >:(
},

I am getting almost all console messages an infinite number of times, without doing anything such as firing the ng-change function. I just add a daily bread to my cart for instance, and then the console gets filled with the following messages, that I have starred in my code.

My theBreadsList is not very long, so there is something going on that it is going repeatedly like this. Even if I broke out of the for loop twice as you will see in my code, it wouldn't explain the fact that it logs to the console all the time, because eventually the loop would not be satisfied, and this wouldn't take to long as has been mentioned.

Please advise, thank you. If you need more information, I am happy to provide.


回答1:


The getOtherOrderDates will be called in each digest cycle so that angular knows whether to update options in select. That's most likely the reason you're seeing this method being called many times.

If you're worried about performance impact of this loop you can build the options upfront inside your controller store it in $scope like so:

$scope.options = $scope.getOtherOrderDates($scope.Bread.text);

whenever $scope.Bread.text changes and then use $scope.options inside your template.




回答2:


To avoid triggering your loops in every digest loop you can use one time binding ::value.

<select ng-options="theorderdate as theorderdate for theorderdate in ::getOtherOrderDates(Bread.text)" 
        ng-model="randomDateRomantic.randomDateRomantic" 
        ng-change="soRomantic(Bread.text)"></select>

Thanks to that expression inside ng-options will be evaluated only once and the watcher will be removed after first evaluation which will stop your function being triggered in next digest loop iterations.

DOCS



来源:https://stackoverflow.com/questions/34579985/ng-options-expression-repeatedly-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!