I have have a page where I am using plupload to upload files and having a weird issue with a ng-repeat not updating properly. Here is the relevant code:
<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
});
}
Here is a trimmed down jsfiddle showing the issue happening:
http://jsfiddle.net/9HuUC/
To reproduce this issue do the following:
What would cause this type of behavior? I mean I know that the data is properly being set in $scope.filesToUpload because I have the console.log() there and even checked it in Batarang and it loods good there but for some reason something else needs to be updated for the display to be updated.
Interestingly enough, I have another ng-repeat that is working fine on the same page. I am wondering if it has anything to do with where the code is (being inside the FilesAdded event on the uploader).
The issue is due to the fact that the FilesAdded callback is executed outside the scope of AngularJS (it's called by the uploader), therefore the scope updates won't be triggered.
To solve this, just add the $scope.$apply
call in the callback, encapsulating your existing code:
$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
});
});
With this update, it's working in the fiddle. For reference see the AngularJS official documentation, $apply method of the scope object: http://docs.angularjs.org/api/ng.$rootScope.Scope
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With