9

angularjs 1.1.4 の ng-view と ng-animate で遊んでいるときに、ディレクティブが 2 回実行されることに気付きました。画面に入るビュー内の要素に対して 1 回、画面から出るビュー内の要素に対して 1 回 (ビューが画面に入ったときに、その要素に対してディレクティブが既に実行されている間)。

私の理解では、ディレクティブは画面に入る要素に対してのみ実行され、画面から出る要素に対しては実行されるべきではありません。または私は何かを逃していますか?

<div ng-app="app">
    <div ng-controller="AppCtrl">
        <div class="btn-group">
            <a class="btn btn-primary" href="./">foo</a>
            <a class="btn btn-primary" href="bar/">bar</a>
        </div>
        <span class="btn btn-success">{{count}}</span>
        <div class="view" ng-view ng-animate="{enter: 'view-enter', leave: 'view-leave'}"></div>
    </div>
</div>
var app = angular.module('app', []);

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when('/', {
            template: '<h1 color>foo</h1>'
        })
        .when('/bar', {
            template: '<h1 color>bar</h1>'
        })
        .otherwise({
            redirectTo: '/'
        });

    $locationProvider.html5Mode(true);
});

app.controller('AppCtrl', function ($scope) {
    $scope.count = 0;
    $scope.incrementCount = function () {
        $scope.count++;
    }
});

app.directive('color', function () {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attrs) {
            // executed once the app inits but
            // twice when you change the view
            $scope.incrementCount();
        }
    }
});

私はこれのためにjsfiddleをセットアップしましたhttp://jsfiddle.net/mediastuttgart/f4FPj/1/

ご覧のとおり、アプリの初期化時にカウンターは 1 を示します。ただし、ナビゲートを開始すると、カウンターは 2 ずつ増加します。

乾杯マイケル

編集

もちろん、回避策として要素にクラスを追加し、ディレクティブでそれをチェックすることもできますが、それは実現すべき方法ではないと思います。

link: function ($scope, $element, $attrs) {
    if ($element.hasClass('processed')) return;
    $element.addClass('processed');
    $scope.incrementCount();
}

http://jsfiddle.net/mediastuttgart/f4FPj/2/

4

2 に答える 2

2

ディレクティブが処理するイベントごとにディレクティブを起動します。このフィドルを参照してください。 leave イベントを削除すると、一度だけ発生します。

<div class="view" ng-view ng-animate="{enter: 'view-enter'}"></div>

http://jsfiddle.net/WmSP8/1/

ドキュメントには、「event1 および event2 属性は、割り当てられたディレクティブに固有のアニメーション イベントを参照する」と記載されていることに注意してください

基本的に、すべてのディレクティブに存在しないカスタム イベントを使用してディレクティブを作成できること、およびアニメーター サービスにより、これらのイベントがディレクティブで発生したときにどのアニメーションを実行するかをディレクティブが認識できるようになるということです。ただし、これは、ディレクティブが ng-animate 属性で処理される各イベントに対して実行される可能性があることを意味します。そのため、enter と leave の両方を構成すると、ディレクティブは両方に対して実行されます。

これをテストするためのコードを実際に書いたことはありません。これはドキュメントの私の解釈にすぎず、jsfiddle は一般的な前提を確認しているようです。

于 2013-05-03T12:27:36.340 に答える
0

この問題は、angular 1.1.5 で解決したようです。このコミットで修正されたとngView: accidentally compiling leaving content (9956baed) 思います https://github.com/angular/angular.js/commit/9956baedd73d5e8d0edd04c9eed368bd3988444b

于 2013-06-25T05:53:08.157 に答える