8

サイトのメイン ページにランダムな位置で表示され、フェード効果と翻訳効果を備えたいくつかのフレーズにアニメーションを作成しようとしています。

ng-repeat 属性内でng-style属性を使用し、HomeController 内で定義された JavaScript 関数を呼び出す ng-style 値を設定して、これを実現します。

このアプローチを使用すると、Angular は例外をスローします: $rootScope:infdig エラー 10 $digest() 反復に達しました。中止します!最後の 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 + '%'
};

}

ここにデモがあります: http://plnkr.co/edit/8sYks589agtLbZCGJ08B?p=preview

4

4 に答える 4

4

@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

于 2015-09-22T16:56:12.630 に答える
2

スタイル生成をディレクティブに移動したソリューションを次に示します。要素を表示する直前に位置が設定されています。これは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.

プランカー: http://plnkr.co/edit/bZB3A5hD7Bc4r4pp1g7V?p=preview

于 2015-09-22T17:11:00.750 に答える
0

問題は、そのような 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 無限 $digest スコープが変更されない場合のループ

于 2015-09-22T16:46:40.543 に答える