我正在创建一个有助于上传CSV文件的指令.我正在使用a <input type="file" ng-hide="true"/>和本机JavaScript FileReader()来执行此操作.当我使用本机选择文件时,一切正常input,但我尝试使用自己的"浏览"按钮自定义文件控件.问题是,当我尝试这样做时,我得到$ apply已经在进行中错误.
这是我的指示
app.directive('skUploader', function ($timeout) {
return {
restrict: 'A',
replace: true,
template: '<div>\
<input type="file" class="uploadControl" ng-hide="false" />\
<input type="text" ng-model="selectedFile" />\
<button type="button" class="btnPlain" ng-click="triggerBrowse()">Browse</button>\
<button type="button" class="btnOrange fRight" ng-click="uploadCSV()">Upload</button>\
<button type="button" class="btnPlain fRight" ng-click="cancel()">Cancel</button>\
</div>',
link: function (scope, elem, attr, ctrl) {
var uploadControl = elem.find('input[type=file]');
var payload = null;
var type = attr.skUploader;
scope.selectedFile = null;
scope.uploadCSV = function () {
$timeout(function () {
alert('Upload Successful');
}, 3000);
}
scope.cancel = function () {
payload = null;
scope.selectedFile = null;
scope.model.showUploadPanel = false;
}
uploadControl.on('change',function () {
var fileHandle = uploadControl[0].files[0];
var reader = new FileReader();
var buffer;
scope.selectedFile = fileHandle.name;
reader.onload = function(){
buffer = reader.result;
payload = parseCSV(buffer);
if (payload) {
// Make API call
if (type == 'mapping') {
console.log(payload);
} else {
}
}
}
if (fileHandle.name.indexOf('.csv') > 0) {
reader.readAsText(fileHandle);
} else {
}
});
function parseCSV(buff){
var entries = [];
entries = buff.split(/\n/);
var json = [];
if (type == 'mapping') {
var formatter = {
iRowNumber: null,
SourceName: null,
DestName: null
};
} else if (type == 'passwords') {
var formatter = {
iRowNumber: null,
SourceCreds: {
EmailAddress: null,
Username: null,
Pwd: null
}
};
} else {
return null;
}
for(var i = 1; i < entries.length - 1; i++){
var split = entries[i].split(',');
var obj = angular.copy(formatter);
var j = 0;
angular.forEach(formatter, function (value, key) {
if (key == 'iRowNumber') {
obj[key] = i;
} else if (key == 'SourceCreds') {
obj[key] = {
EmailAddress: split[0],
Username: split[1],
Pwd: split[2]
};
}else{
obj[key] = split[j];
j++;
}
});
json.push(obj);
}
return json;
}
scope.triggerBrowse = function () {
uploadControl.trigger('click'); // THIS IS WHAT CAUSES THE ERROR
}
}
};
});
Run Code Online (Sandbox Code Playgroud)
当我使用"浏览"按钮进行trigger('click')uploadControl时,Angular会发出错误
Error: [$rootScope:inprog] $apply already in progress
Run Code Online (Sandbox Code Playgroud)
但我没有scope.$apply()在任何地方使用,所以我无法弄清楚问题.它应该只是触发<input type="file"/>应该启动OS本机文件资源管理器的click事件.
更新
这可能与这个问题有关吗?
更新2
经过一些更多的研究后,我发现这个Git问题,vojta(一个核心AngularJS dev)回应说我们需要将事件包装成一个$timeout.我这样做了,它确实有效!有人可以向我解释为什么需要这么详细吗?谢谢
Car*_*ers 24
当您在不使用Angular函数的情况下更改范围时(例如,使用jQuery click事件处理程序而不是ngClick),它会变得非常脾气暴躁.有时它只是忽略你的变化,直到它再次运行,有时你会在一个特别脾气暴躁的时刻抓住它,因为它已经忙于其他事情并且它会给你带来的错误.
要成为Angular友好的,您需要使用其事件系统来更新范围.如果你不能这样做,你有办法告诉它你正在进行更改,以便它可以按照自己的时间表处理这些更改.这种方式是$timeout- 一个timeout与更新循环集成的Angular友好版本的JavaScript .在没有持续时间参数的情况下调用它只意味着"下次您准备好更改范围时,请执行此操作."
$apply顺便说一句,打电话给自己并不是一个好主意$timeout.
| 归档时间: |
|
| 查看次数: |
5211 次 |
| 最近记录: |