Javascript AngularJS与FileReader和$scope有问题。$watch?
我有一个奇怪的问题(至少对我来说),希望有人能帮上忙。也许我只是想错了。尝试用javascript处理文件对我来说是全新的 我有一个指令,其模板如下所示:Javascript AngularJS与FileReader和$scope有问题。$watch?,javascript,angularjs,filereader,Javascript,Angularjs,Filereader,我有一个奇怪的问题(至少对我来说),希望有人能帮上忙。也许我只是想错了。尝试用javascript处理文件对我来说是全新的 我有一个指令,其模板如下所示: <input type="file" ng-file-select ng-model="files"> <button ng-click="onFileSelect()">Upload</button> 我选择一个文件,然后单击上载按钮。(文件内容)的console.log未定义。只有当我第二次单击按钮时
<input type="file" ng-file-select ng-model="files">
<button ng-click="onFileSelect()">Upload</button>
我选择一个文件,然后单击上载按钮。(文件内容)的console.log未定义。只有当我第二次单击按钮时,它才有值
如果我取消对调试器的注释,$scope.file\u contents在我检查它时有一个值
所以,文件内容需要一段时间才能设置好(这是意料之中的),但$watch似乎从未注意到?有什么奇怪的原因吗?$watch不适用于FileReader对象吗
编辑1:
好的。这里有更多的信息。根据PSL的建议,我现在拥有如下代码:
$scope.onFileSelect = function() {
reader = new FileReader();
reader.onload = function() {
file_contents = this.result;
upload_file($scope.files[0],file_contents);
};
reader.readAsArrayBuffer($scope.files[0]);
};
upload_file = function(file,file_contents) {
<lots of cool file_contents-y stuff>
};
这是怎么回事?Watch似乎从未注意到,因为您正在更新角度上下文之外的范围。您需要使用
scope.$apply()
或在onload
异步函数中使用$timeout等任何其他方式手动调用摘要循环。最好将手表移到onFileSelect方法之外,否则每次上传点击都会继续累积观看的手表
尝试:
$scope.onFileSelect=function(){
reader=newfilereader();
reader.onload=函数(){
$scope.file_contents=this.result;
$scope.$apply();/Watch似乎从未注意到,因为您正在角度上下文之外更新范围。您需要使用scope.$apply()手动调用摘要循环
或在onload
异步函数中使用$timeout等任何其他方法。最好将手表移到onfleleselect方法之外,否则每次上传点击都会继续累积观看的内容
尝试:
$scope.onFileSelect=function(){
reader=newfilereader();
reader.onload=函数(){
$scope.file_contents=this.result;
$scope.$apply();/有一种更好的方法。。
您可以这样定义一个指令
//directive.js
(function() {
angular.module('<yourApp>').
directive('fileread', ['$parse', function($parse){
// Runs during compile
return {
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
var model = $parse(iAttrs.fileread);
var modelSetter = model.assign;
iElm.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, iElm[0].files[0]);
});
});
}
};
}]);
})();
//controller.js
...
$scope.photo.data = null;
...
$scope.photo.upload = function() {
fd = new FormData();
fd.append('<name_of_form_field_the_photo_should_be_sent_as>', $scope.photo.data);
$http.post('<url>', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
//directive.js
(功能(){
角模(“”)。
指令('fileread',['$parse',函数($parse){
//在编译期间运行
返回{
限制:“A”,
链接:功能($scope、iElm、iAttrs、controller){
var模型=$parse(iAttrs.fileread);
var modelSetter=model.assign;
iElm.bind('change',function(){
$scope.$apply(函数(){
modelSetter($scope,iElm[0]。文件[0]);
});
});
}
};
}]);
})();
然后在控制器(或其他指令)中创建如下模型
//directive.js
(function() {
angular.module('<yourApp>').
directive('fileread', ['$parse', function($parse){
// Runs during compile
return {
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
var model = $parse(iAttrs.fileread);
var modelSetter = model.assign;
iElm.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, iElm[0].files[0]);
});
});
}
};
}]);
})();
//controller.js
...
$scope.photo.data = null;
...
$scope.photo.upload = function() {
fd = new FormData();
fd.append('<name_of_form_field_the_photo_should_be_sent_as>', $scope.photo.data);
$http.post('<url>', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
//controller.js
...
$scope.photo.data=null;
...
$scope.photo.upload=函数(){
fd=新FormData();
fd.append(“”,$scope.photo.data);
$http.post(“”,fd{
请求:angular.identity,
标题:{'Content-Type':未定义}
})
最后是html
<input type = 'file' fileread = "photo.data">
<button ng-click = "photo.upload"> </button>
我希望这能有所帮助。有一种更好的方法。。
您可以这样定义一个指令
//directive.js
(function() {
angular.module('<yourApp>').
directive('fileread', ['$parse', function($parse){
// Runs during compile
return {
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
var model = $parse(iAttrs.fileread);
var modelSetter = model.assign;
iElm.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, iElm[0].files[0]);
});
});
}
};
}]);
})();
//controller.js
...
$scope.photo.data = null;
...
$scope.photo.upload = function() {
fd = new FormData();
fd.append('<name_of_form_field_the_photo_should_be_sent_as>', $scope.photo.data);
$http.post('<url>', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
//directive.js
(功能(){
角模(“”)。
指令('fileread',['$parse',函数($parse){
//在编译期间运行
返回{
限制:“A”,
链接:功能($scope、iElm、iAttrs、controller){
var模型=$parse(iAttrs.fileread);
var modelSetter=model.assign;
iElm.bind('change',function(){
$scope.$apply(函数(){
modelSetter($scope,iElm[0]。文件[0]);
});
});
}
};
}]);
})();
然后在控制器(或其他指令)中创建如下模型
//directive.js
(function() {
angular.module('<yourApp>').
directive('fileread', ['$parse', function($parse){
// Runs during compile
return {
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
var model = $parse(iAttrs.fileread);
var modelSetter = model.assign;
iElm.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, iElm[0].files[0]);
});
});
}
};
}]);
})();
//controller.js
...
$scope.photo.data = null;
...
$scope.photo.upload = function() {
fd = new FormData();
fd.append('<name_of_form_field_the_photo_should_be_sent_as>', $scope.photo.data);
$http.post('<url>', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
//controller.js
...
$scope.photo.data=null;
...
$scope.photo.upload=函数(){
fd=新FormData();
fd.append(“”,$scope.photo.data);
$http.post(“”,fd{
请求:angular.identity,
标题:{'Content-Type':未定义}
})
最后是html
<input type = 'file' fileread = "photo.data">
<button ng-click = "photo.upload"> </button>
我希望它有帮助。不幸的是,没有。我必须发送多部分/混合,如果不创建自己的代码来发送数据,就无法执行此操作。我不能使用“内容类型”:未定义,因为它默认为多部分/表单数据。不幸的是,没有。我必须发送多部分/混合,如果不创建自己的代码来发送数据,就无法执行此操作数据。我不能使用“内容类型”:未定义,因为它默认为multipart/form-data。这就是工作方式。但是,我遇到了这些愚蠢的$digest错误。我可以忽略它们吗?我尝试了1000种不同的方法来消除它们,但都不起作用。$timeout不是一个解决方案。如果出于某种原因,我决定单击“上载”,请等待或者将其上载,然后再次单击上载,在某个时候,我会得到$digest错误。我将在下面发布更多代码的后续内容。我不再使用$scope做任何事情,也无法理解为什么它仍然会给我带来问题。@JimMacKenzie您不应该得到digest错误,您有演示吗?我从未设置过JSFIDLE或类似的工具。它是这需要一段时间。你没有作用域。$apply,对吗?如果有,请删除它并尝试。我不知道你正在使用的所有插件。因此必须假设没有。我的代码中没有任何地方使用$scope。$apply。直到你提到它,我才知道它。我已经用我的新代码更新了这个问题。没有$scope。$apply。这就是工作方式g、 但是,我遇到了这些愚蠢的$digest错误。我可以忽略它们吗?我尝试了1000种不同的方法来消除它们,但都不起作用。$timeout不是一个解决方案。如果出于某种原因,我决定单击上载,等待它上载,然后再次单击上载,在某个时候,我会得到$digest错误