Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS与FileReader和$scope有问题。$watch?_Javascript_Angularjs_Filereader - Fatal编程技术网

Javascript AngularJS与FileReader和$scope有问题。$watch?

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未定义。只有当我第二次单击按钮时

我有一个奇怪的问题(至少对我来说),希望有人能帮上忙。也许我只是想错了。尝试用javascript处理文件对我来说是全新的

我有一个指令,其模板如下所示:

<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错误