2

ファイルのアップロード中に( を介して) イベントを発生させるファイル アップロード ディレクティブがあります。これは、進行状況バーを更新するためscope.$emitにコントローラーで ( を介して) キャッチされます。scope.$onファイル アップロード ディレクティブはng-switch-ed アウトされるため、ユーザーはファイルのアップロード中にファイルに関するその他の情報を入力できます。彼らがこれをしている間、プログレスバーが更新され続けることを望みます。これはバージョン 1.0.2 では問題なく動作していましたが、1.0.4 では壊れているようです。

私が作成した jsFiddleは大幅に単純化されていますが、問題が示されています。ページが最初に読み込まれると、ディレクティブからイベントが発生し、コントローラーでキャッチされ、すべてが期待どおりに更新されます。ただし、ディレクティブがng-switch削除されるようにドロップダウンを変更すると、イベントが捕捉されなくなります。コンソールを見ると、イベントはまだ取得$emit中ですが、コントローラーはそれをキャッチしなくなります。(http://jsfiddle.net/uysAM/1/ )に置いても$on、まだ同じ問題があります。イベントがまだ処理されている場合、なぜスコープはそれをキャッチしなくなるのでしょうか?$rootScope$emit

上部のタグの src を<script>1.0.2 を使用するように変更すると、問題なく動作します。これは最新バージョンの新しいバグですか? 助けてくれてありがとう。

4

1 に答える 1

0

これは範囲の問題です。これが私がそれを理解する方法です。

foo=1 の場合のスコープチェーン

  • MyCtrl のスコープ <- ここでキャッチ
    • foo="1" に対する ngSwitch のスコープ
      • myDirective のスコープ <- ここで出力します

スコープ チェーンはそのままで、発行されたイベントを問題なくキャッチできます。

foo=2 の場合、スコープチェーンが変更されます

  • MyCtrl のスコープ
    • null <- 破棄され、メモリ管理のために 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;
        }
    };
});
于 2013-06-21T23:57:15.080 に答える