问题
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 option
s 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