AngularJS: $rootScope:infdig 在 ng-repeat 中调用 ng-style 函数时出错
AngularJS: $rootScope:infdig error when calling a ng-style function inside ng-repeat
我正在尝试为一些短语制作动画,这些短语将显示在网站主页上,位置随机,并具有淡入淡出和平移效果。
我会在 ng-repeat 属性中使用 ng-style 属性 并设置 ng-style 值调用 JavaScript HomeController 内部定义的函数。
使用此方法导致 angular 抛出异常:$rootScope:infdig error 10 $digest() iterations reached.中止!观察者在最后 5 次迭代中解雇
我读了很多关于此的内容,但没有解决方案解决我的问题。
有人可以帮助我吗?
这是index.html的一部分:
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text" ng-repeat="phrase in Phrases" ng-style="getTopLeftPosition()">{{phrase}}</h3>
</div>
控制器函数如下:
$scope.getTopLeftPosition = function() {
var top = randomBetween(10, 90);
var left = getRandomTwoRange(5, 30, 70, 80);
return {
top: top + '%',
left: left + '%'
};
}
这样你就可以管理你的 ngstyle
$scope.getTopLeftPosition = function() {
$scope.top = randomBetween(20, 90);
$socpe.left = getRandomTwoRange(5, 30, 70, 80);
}
function getRandomTwoRange(firstStart, firstEnd, secondStart, secondEnd) {
var isLower = (Math.random() * 2) < 1;
if (isLower)
return randomBetween(firstStart, firstEnd);
else
return randomBetween(secondStart, secondEnd);
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
<body>
<div ng-controller="HomeController">
<div class="row" style="height:100%">
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text " ng-repeat="phrase in Phrases" ng-style="{ 'top' : top, 'left' : left }">{{phrase}}</h3>
</div>
</div>
</div>
我认为问题在于您不能那样绑定 ng-style。它认为它需要不断地调用 getTopLeftPosition。
我在这里得到了某种工作。时间有点不对,但没有更多的错误。这里我用 $interval 来重复:
请在此处查看:http://plnkr.co/edit/B4iMZXMvZFoYMCKNvVrc?p=preview
$scope.phrase_style = getTopLeftPosition();
function change_phrase_style() {
$scope.phrase_style = getTopLeftPosition();
}
function start_interval() {
change_phrase_style();
$interval(function(){
change_phrase_style();
}.bind(this), 5000);
}
setTimeout(start_interval, 1000);
这也可能是相关的:angularjs infinite $digest Loop when no scope changes
@Hieu Le 暗示了这个问题,但你的问题是因为你总是在你的 getTopLeftPosition
函数中返回一个随机位置,所以每次都会调用 angularjs 摘要循环来实际传播观察者的变化。这导致它一遍又一遍地保持 运行。
您可以做的是预先计算您的随机位置,然后在您的 html 中使用它。
例如,在你的激活函数中你可以这样做:
function activate() {
$scope.Phrases = ["Phrase 1", "Phrase 2", "Phrase 3", "Phrase 4", "Phrase 5", "Phrase 6"];
$scope.PhrasesAndPositions = $scope.Phrases.map(function(phrase){
return {
phrase: phrase,
position: getTopLeftPosition()
}
});
}
然后您可以将 html 更改为如下内容:
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text" ng-repeat="pap in PhrasesAndPositions" ng-style="pap.position">{{pap.phrase}}</h3>
</div>
这是我所做更改的工作原理:http://plnkr.co/edit/FD9hYX9Q5wUkW2q7y86M?p=preview
这是一个解决方案,我将您的样式生成移到了指令中。在显示元素之前设置位置。由于这是一个 CSS 更改,我也修改了样式,这样位置就不会过渡。
这是指令。我排除的代码没有改变:
app.directive('animatePhrases', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
setTimeout(function() {
...
}, 1000);
function changeText() {
var currentActive = $('.phrasesContainer .active');
var nextActive = currentActive.next();
currentActive.toggleClass('active');
if (nextActive.length == 0)
nextActive = $('.phrasesContainer .flying-text').first();
nextActive.css(getTopLeftPosition()); // Add this
nextActive.toggleClass('active');
setTimeout(changeText, 5000);
}
function getTopLeftPosition() {
...
}
function getRandomTwoRange(firstStart, firstEnd, secondStart, secondEnd) {
...
}
function randomBetween(min, max) {
...
}
}
};
});
CSS:
.flying-text {
transition: opacity 2s ease-in-out, margin 2s ease-in-out;
position: absolute;
opacity: 0;
font-size: 1.5em;
}
在您的 HTML 中,只需删除 ng-style
。
我正在尝试为一些短语制作动画,这些短语将显示在网站主页上,位置随机,并具有淡入淡出和平移效果。
我会在 ng-repeat 属性中使用 ng-style 属性 并设置 ng-style 值调用 JavaScript HomeController 内部定义的函数。
使用此方法导致 angular 抛出异常:$rootScope:infdig error 10 $digest() iterations reached.中止!观察者在最后 5 次迭代中解雇
我读了很多关于此的内容,但没有解决方案解决我的问题。 有人可以帮助我吗?
这是index.html的一部分:
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text" ng-repeat="phrase in Phrases" ng-style="getTopLeftPosition()">{{phrase}}</h3>
</div>
控制器函数如下:
$scope.getTopLeftPosition = function() {
var top = randomBetween(10, 90);
var left = getRandomTwoRange(5, 30, 70, 80);
return {
top: top + '%',
left: left + '%'
};
}
这样你就可以管理你的 ngstyle
$scope.getTopLeftPosition = function() {
$scope.top = randomBetween(20, 90);
$socpe.left = getRandomTwoRange(5, 30, 70, 80);
}
function getRandomTwoRange(firstStart, firstEnd, secondStart, secondEnd) {
var isLower = (Math.random() * 2) < 1;
if (isLower)
return randomBetween(firstStart, firstEnd);
else
return randomBetween(secondStart, secondEnd);
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
<body>
<div ng-controller="HomeController">
<div class="row" style="height:100%">
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text " ng-repeat="phrase in Phrases" ng-style="{ 'top' : top, 'left' : left }">{{phrase}}</h3>
</div>
</div>
</div>
我认为问题在于您不能那样绑定 ng-style。它认为它需要不断地调用 getTopLeftPosition。
我在这里得到了某种工作。时间有点不对,但没有更多的错误。这里我用 $interval 来重复:
请在此处查看:http://plnkr.co/edit/B4iMZXMvZFoYMCKNvVrc?p=preview
$scope.phrase_style = getTopLeftPosition();
function change_phrase_style() {
$scope.phrase_style = getTopLeftPosition();
}
function start_interval() {
change_phrase_style();
$interval(function(){
change_phrase_style();
}.bind(this), 5000);
}
setTimeout(start_interval, 1000);
这也可能是相关的:angularjs infinite $digest Loop when no scope changes
@Hieu Le 暗示了这个问题,但你的问题是因为你总是在你的 getTopLeftPosition
函数中返回一个随机位置,所以每次都会调用 angularjs 摘要循环来实际传播观察者的变化。这导致它一遍又一遍地保持 运行。
您可以做的是预先计算您的随机位置,然后在您的 html 中使用它。
例如,在你的激活函数中你可以这样做:
function activate() {
$scope.Phrases = ["Phrase 1", "Phrase 2", "Phrase 3", "Phrase 4", "Phrase 5", "Phrase 6"];
$scope.PhrasesAndPositions = $scope.Phrases.map(function(phrase){
return {
phrase: phrase,
position: getTopLeftPosition()
}
});
}
然后您可以将 html 更改为如下内容:
<div class="phrasesContainer" animate-phrases="">
<h3 class="flying-text" ng-repeat="pap in PhrasesAndPositions" ng-style="pap.position">{{pap.phrase}}</h3>
</div>
这是我所做更改的工作原理:http://plnkr.co/edit/FD9hYX9Q5wUkW2q7y86M?p=preview
这是一个解决方案,我将您的样式生成移到了指令中。在显示元素之前设置位置。由于这是一个 CSS 更改,我也修改了样式,这样位置就不会过渡。
这是指令。我排除的代码没有改变:
app.directive('animatePhrases', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
setTimeout(function() {
...
}, 1000);
function changeText() {
var currentActive = $('.phrasesContainer .active');
var nextActive = currentActive.next();
currentActive.toggleClass('active');
if (nextActive.length == 0)
nextActive = $('.phrasesContainer .flying-text').first();
nextActive.css(getTopLeftPosition()); // Add this
nextActive.toggleClass('active');
setTimeout(changeText, 5000);
}
function getTopLeftPosition() {
...
}
function getRandomTwoRange(firstStart, firstEnd, secondStart, secondEnd) {
...
}
function randomBetween(min, max) {
...
}
}
};
});
CSS:
.flying-text {
transition: opacity 2s ease-in-out, margin 2s ease-in-out;
position: absolute;
opacity: 0;
font-size: 1.5em;
}
在您的 HTML 中,只需删除 ng-style
。