ng-view和ng-animate执行指令两次

时间:2013-04-23 05:29:04

标签: javascript angularjs ng-animate

当我在使用angularjs 1.1.4的ng-view和ng-animate时,我发现指令执行了两次。一次用于进入屏幕的视图中的元素,另一次用于离开屏幕的视图中的元素(当视图进入屏幕时已经为元素执行了指令)。

根据我的理解,指令只应对进入屏幕的元素执行,而不是对离开的元素执行。或者我错过了什么?

<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();
        }
    }
});

我为这个http://jsfiddle.net/mediastuttgart/f4FPj/1/

设置了一个jsfiddle

正如您所看到的,当应用程序进入时,计数器会显示1。但是如果你开始导航,计数器会增加2。

欢呼声 迈克尔

修改

当然一种解决方法可能是在元素中添加一个类并在指令中检查它 - 但我想这不是它应该完成的方式。

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

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

2 个答案:

答案 0 :(得分:2)

它将为指令处理的每个事件触发指令。看到这个小提琴,如果你删除了离开事件,它只会触发一次。

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

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

请注意文档说“event1和event2属性引用特定于已分配的指令的动画事件。”(http://code.angularjs.org/1.1.4/docs/api/ng.directive:ngAnimate

它实质上是说您可以使用所有指令中不存在的自定义事件构建指令,并且动画师服务将允许您的指令知道在指令中触发这些事件时要运行的动画。但是,这意味着您的指令可能会针对ng-animate属性中处理的每个事件执行。因此,当您同时配置enter和leave时,指令将同时为它们执行。

我实际上没有编写任何代码来测试这个,这只是我对文档的解释,并且jsfiddle似乎证实了一般的前提。

答案 1 :(得分:0)

这个问题似乎已经消失了,角度为1.1.5。猜猜这个提交修复了ngView: accidentally compiling leaving content (9956baed) https://github.com/angular/angular.js/commit/9956baedd73d5e8d0edd04c9eed368bd3988444b