4

plupload を使用してファイルをアップロードしているページがあり、ng-repeat が適切に更新されないという奇妙な問題が発生しています。関連するコードは次のとおりです。

<div ng:app>
  <div name="myForm" ng-controller="Ctrl">
    <input ng-model="test" type="text" />{{test}}<div id="container" class="controls">
    <div id="filelist">
      <div ng-repeat="file in filesToUpload">{{file.name}} ({{file.size}}) <b>{{file.percent}}</b></div>
      </div>
      <br />
      <a id="pickfiles" href="#">[Select files]</a>
    </div>
  </div>
</div>​

function Ctrl($scope) {
    $scope.test = '';$scope.filesToUpload = [{id: 1, name: 'test', size: '123kb'}];

    $scope.addItem = function(object) {
        $scope.filesToUpload.push(object);
    }

    $scope.uploader = new plupload.Uploader({
        runtimes : 'html5,flash,browserplus,gears',
        browse_button : 'pickfiles',
        container : 'container',
        max_file_size : '10mb',
        url : 'upload.php',
        flash_swf_url : '/plupload/js/plupload.flash.swf'
    });

    $scope.uploader.init();

    $scope.uploader.bind('FilesAdded', function(up, files) {
        $scope.filesToUpload = [];
        $.each(files, function(i, file) {
            $scope.addItem({
                id: file.id,
                name: file.name,
                size: plupload.formatSize(file.size)
            });
        });

        console.log($scope.filesToUpload);

        up.refresh(); // Reposition Flash/Silverlight
    });
}​

これは、問題が発生していることを示すトリミングされた jsfiddle です。

http://jsfiddle.net/9HuUC/

この問題を再現するには、次の手順を実行します。

  1. [select files] をクリックして、いくつかのファイルを選択します (出力のどこにもファイルが表示されないことに注意してください)。
  2. 入力ボックスに任意の文字を入力します (魔法のように、選択したファイルが表示されます)。

この種の動作の原因は何ですか? つまり、データが $scope.filesToUpload に適切に設定されていることを知っているということです。そこに console.log() があり、Batarang でそれをチェックしたからです。更新されます。

興味深いことに、同じページで正常に動作している別の ng-repeat があります。コードの場所 (アップローダーの FilesAdded イベント内) と関係があるかどうか疑問に思っています。

4

1 に答える 1

8

この問題は、FilesAdded コールバックが AngularJS のスコープ外で実行される (アップローダーによって呼び出される) ため、スコープの更新がトリガーされないことが原因です。

これを解決する$scope.$applyには、コールバックに呼び出しを追加して、既存のコードをカプセル化します。

$scope.uploader.bind('FilesAdded', function(up, files) {
    $scope.$apply( function() {
        $scope.filesToUpload = [];
        $.each(files, function(i, file) {
            $scope.addItem({
                id: file.id,
                name: file.name,
                size: plupload.formatSize(file.size)
            });
        });

        console.log($scope.filesToUpload);

        up.refresh(); // Reposition Flash/Silverlight
    });
});

今回の更新により、フィドルで動作するようになりました。参照については、AngularJS の公式ドキュメントスコープオブジェクト の$applyメソッドを参照してください: http://docs.angularjs.org/api/ng .$rootScope.Scope

于 2012-10-31T17:25:59.237 に答える