AngularJS ngRepeat未正确更新显示

时间:2012-10-31 17:10:02

标签: angularjs plupload

我有一个页面,我使用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. 点击[选择文件]并选择几个文件(注意你没有看到输出上任何地方显示的文件)
  2. 在输入框中输入任何字符(神奇地显示您选择的文件)
  3. 什么会导致这种行为?我的意思是我知道数据在$ scope.filesToUpload中正确设置,因为我在那里有console.log()甚至在Batarang中检查它并且它在那里很好但是由于某些原因需要更新显示器的其他内容待更新。

    有趣的是,我有另一个ng-repeat在同一页面上正常工作。我想知道它是否与代码的位置有关(在上传者的FilesAdded事件中)。

1 个答案:

答案 0 :(得分: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