为什么在“ng-switch”-ing时事件停止被捕获

时间:2013-02-07 06:14:34

标签: angularjs angularjs-directive

我有一个文件上传指令,用于在上传文件时触发事件(通过scope.$emit),然后在我的控制器中捕获(通过scope.$on)以更新进度条。文件上载指令获取ng-switch - 因此用户可以在上载文件时填写有关该文件的其他信息。我希望进度条在执行此操作时不断更新。对于版本1.0.2,这一切都运行得很好,但现在似乎在1.0.4中已经破解了。

The jsFiddle I created大大简化了,但它显示了问题。首次加载页面时,会从指令触发该事件,并在控制器中捕获该事件,并按预期更新所有内容。但是,如果您更改下拉列表以使指令变为ng-switch,则事件将停止被捕获。如果您在控制台中查看,该事件仍在进行$emit编辑,但控制器只是停止捕获它。即使我将$on放在$rootScopehttp://jsfiddle.net/uysAM/1/)上,它仍会遇到同样的问题。如果事件仍然是$emit - ed,为什么范围会停止捕获它?

如果你更改顶部的<script>标签中的src使用1.0.2,它就可以了。这是最新版本的新bug吗?谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

这是范围问题。我就是这样理解的。

foo = 1时的范围链

  • MyCtrl的范围&lt; - 我们赶上这里
    • ngSwitch的foo范围=“1”
      • myDirective的范围&lt; - 我们在这里发光

范围链完好无损,我们可以毫无问题地捕获发出的事件。

当foo = 2

时,范围链会发生变化
  • MyCtrl的范围
    • null&lt; - 销毁并设置为null以进行内存管理。
      • myDirective的范围

范围链不再完整。发出的事件不会传播到myDirective已清理的父作用域。此清理可能已作为1.0.4中的功能添加。

这是我解决问题的方法。我使用fileLoader服务在指令和控制器之间共享状态。http://jsfiddle.net/apBZX/

var myApp = angular.module("myApp", [])

myApp.controller('MyCtrl', function ($scope, $rootScope, fileLoader) {
    $scope.$watch(function () {
        return fileLoader.numberOfloadedFiles;
    }, function (numberOfLoadedFiles) {
        $scope.numberOfLoadedFiles = numberOfLoadedFiles;
    });
    $scope.foo = 1;
});

myApp.directive("myDirective", function (fileLoader) {
    return {
        restrict: 'A',
        replace: true,
        scope: {},
        template: '<div>I am the directive</div>',
        link: function (scope, element, attrs) {
            if (!fileLoader.isLoading) {
                fileLoader.loadFiles(scope);
            }
        }
    }
});

myApp.service("fileLoader", function () {
    return {
        numberOfloadedFiles: 0,
        isLoading: false,
        loadFiles: function (scope) {
            var self = this;
            setInterval(function () {
                scope.$apply(function(){
                    self.numberOfloadedFiles++;
                });
            }, 1000);
            self.isLoading = true;
        }
    };
});