Javascript 角度文件上载指令不更新控制器模型

Javascript 角度文件上载指令不更新控制器模型,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我试图遵循这一点,但无法让它工作 我的角度控制器正在记录指令中创建的模型的未定义的。 下面是我的教程作者创建的一个工作实例 问题是视图可以找到$scope.myFile,但控制器没有($scope.myFile是未定义的) 该视图显示{{myFile.name}(例如my image.jpg)。myFile变量是一个JS对象,包含选定文件上的数据。这个很好用。该指令似乎在为模型指定选定文件的值(从而在视图中正确显示该文件) 在控制器中,我只需记录$scope.myFile。这是从上面HTML中的

我试图遵循这一点,但无法让它工作

我的角度控制器正在记录指令中创建的模型的
未定义的
。
下面是我的教程作者创建的一个工作实例

问题是视图可以找到
$scope.myFile
,但控制器没有(
$scope.myFile
未定义的

该视图显示
{{myFile.name}
(例如
my image.jpg
)。
myFile
变量是一个JS对象,包含选定文件上的数据。这个很好用。该指令似乎在为模型指定选定文件的值(从而在视图中正确显示该文件)

在控制器中,我只需记录
$scope.myFile
。这是从上面HTML中的按钮调用的。 理想情况下,我会在这里将文件上载到服务器,但我不能,因为
$scope.myFile
未定义

$scope.uploadDocs = function() {
  var file = $scope.myFile;
  console.log($scope.myFile);
};

有人能告诉我为什么视图会接收
$scope.myFile
,但控制器会记录
未定义的
以查看
$scope.myFile

我在尝试从控制器访问指令变量时遇到了相同的问题。在我的情况下,我可以使控制器可以使用
myFile
,但我必须从指令中将其分配给
scope.$parent.$parent.myFile
。我不想为了访问变量而对祖先进行硬编码,所以我最终使用了一个服务在指令和控制器之间共享变量:

.factory('fileService', function() {
    var files = [];
    return files;
})
我的指令代码更改为使用服务,而不是教程中使用的
attrs.fileModel

.directive('fileModel', ['$parse', 'fileService', function ($parse, fileService) {
    return {
        restrict: 'A',
        link: function(scope, element) {
            element.bind('change', function(){
                scope.$apply(function(){
                    if (element[0].files != undefined) {
                        fileService.push(element[0].files[0]);
                        console.log('directive applying with file');
                    }
                });
            });
        }
    };
}])
然后,将fileService注入控制器后,我可以直接从fileService访问该文件:

$scope.uploadDocs = function() {
    console.log(fileService);
};

我看过该教程,但选择使用此库,使文件上传无缝:

尝试以下解决方案: HTML代码:

<div class="btn-header">
    <label for="attachment" class="control-label">Attachment</label>
    <div class="has-feedback">
        <input type="file" id="fileUpload" name="attachment" ng-disabled="BRPTab.BRPTelePhonyandTestScipt.Checked"
               class="form-control" data-ak-file-model="BRPTab.tutorial.attachment" />
        <span class="form-control-feedback" aria-hidden="true"></span>
        <div class="help-block with-errors"></div>
    </div>
</div>
如果你们面临任何问题,请告诉我。

试试下面的代码

                <html>

               <head>
                  <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
               </head>

               <body ng-app = "myApp">

                  <div ng-controller = "myCtrl">
                     <input type = "file" file-model = "myFile"/>
                     <button ng-click = "uploadFile()">upload me</button>
                  </div>

                  <script>
                     var myApp = angular.module('myApp', []);

                     myApp.directive('fileModel', ['$parse', function ($parse) {
                        return {
                           restrict: 'A',
                           link: function(scope, element, attrs) {
                              var model = $parse(attrs.fileModel);
                              var modelSetter = model.assign;

                              element.bind('change', function(){
                                 scope.$apply(function(){
                                    modelSetter(scope, element[0].files[0]);
                                 });
                              });
                           }
                        };
                     }]);

                     myApp.service('fileUpload', ['$http', function ($http) {
                        this.uploadFileToUrl = function(file, uploadUrl){
                           var fd = new FormData();
                           fd.append('file', file);

                           $http.post(uploadUrl, fd, {
                              transformRequest: angular.identity,
                              headers: {'Content-Type': undefined}
                           })

                           .success(function(){
                           })

                           .error(function(){
                           });
                        }
                     }]);

                     myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
                        $scope.uploadFile = function(){
                           var file = $scope.myFile;

                           console.log('file is ' );
                           console.dir(file);

                           var uploadUrl = "/fileUpload";
                           fileUpload.uploadFileToUrl(file, uploadUrl);
                        };
                     }]);

                  </script>

               </body>
            </html>

上传我
var myApp=angular.module('myApp',[]);
myApp.directive('fileModel',['$parse',function($parse){
返回{
限制:“A”,
链接:函数(范围、元素、属性){
var model=$parse(attrs.fileModel);
var modelSetter=model.assign;
元素绑定('change',function()){
作用域$apply(函数(){
modelSetter(作用域,元素[0]。文件[0]);
});
});
}
};
}]);
myApp.service('fileUpload',['$http',函数($http){
this.uploadFileToUrl=函数(文件,uploadUrl){
var fd=新FormData();
fd.append('file',file);
$http.post(上传URL、fd、{
请求:angular.identity,
标题:{'Content-Type':未定义}
})
.success(函数(){
})
.错误(函数(){
});
}
}]);
myApp.controller('myCtrl',['$scope','fileUpload',函数($scope,fileUpload){
$scope.uploadFile=函数(){
var file=$scope.myFile;
log('file is');
console.dir(文件);
var uploadUrl=“/fileUpload”;
uploadFileToUrl(文件,uploadUrl);
};
}]);

这个问题可以在几个角度版本中看到,其中file object不能设置为scope变量。作为一种变通方法,将字段传递给控制器,使用此文件对象进行上载(不是从范围)

HTML表单

<form>
    <div class="form-group">
                    <label for="myFileField">Select a file: </label> 
                    <input type="file" file-model="myFile" /> <label>File Name:</label> 
                    <input type="text" ng-model="filename"></input>
                </div>
                <button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button>
            </form>

希望这能解决问题

尝试将我的文件初始化为控制器的第一行:
$scope.myFile={}这主要是点问题,我对您提供的代码进行了修改,效果很好:今天遇到了这个问题。将“myFile”传递到像这样的
uploadDocs(myFile)
函数中似乎可以做到这一点@akinwale为meI工作的解决方案与相同的JSFIDLE有完全相同的问题,出于某种原因,它在我的代码中不起作用,但在小提琴中可以很好地工作@Akinwale的解决方案对我很有效,但在挣扎了三个小时之后,我非常想知道为什么它不起作用!这个解决方法很好,但是理解这个问题对我来说很重要。当你使用ng annotate时,modelSetter也会遇到同样的问题,除非我使用服务来共享变量,否则modelSetter对我不起作用。我仍然非常想知道为什么Q中的教程可以很好地工作(对我也是如此)但是在我自己的代码中实现了它,它没有-我得到了与未定义$scope.myFile的OP相同的错误。尽管如此,这个解决方案还是有效的,而且很容易理解,因此格伦赢得了赏金。
    AppService.factory("entityService", ["akFileUploaderService", function(akFileUploaderService) {
    var saveTutorial = function(tutorial, url) {

        return akFileUploaderService.saveModel(tutorial, url);
    };
    return {
        saveTutorial: saveTutorial
    };
}]);

(function() {
    "use strict"
    angular.module("akFileUploader", [])
        .factory("akFileUploaderService", ["$q", "$http",
            function($q, $http) {
                var getModelAsFormData = function(data) {
                    var dataAsFormData = new FormData();
                    angular.forEach(data, function(value, key) {
                        dataAsFormData.append(key, value);
                    });

                    return dataAsFormData;
                };

                var saveModel = function(data, url) {


                    var deferred = $q.defer();
                    $http({
                        url: url,
                        method: "POST",
                        //data:
                        //    {
                        //        tutorial: getModelAsFormData(data),
                        //        Object: Obj
                        //    },
                        //params: Indata,
                        data: getModelAsFormData(data),
                        transformRequest: angular.identity,
                        headers: {
                            'Content-Type': undefined
                        }
                    }).success(function(result) {

                        deferred.resolve(result);
                    }).error(function(result, status) {
                        deferred.reject(status);
                    });
                    return deferred.promise;
                };

                return {
                    saveModel: saveModel
                }

            }
        ])
        .directive("akFileModel", ["$parse",
            function($parse) {
                return {
                    restrict: "A",
                    link: function(scope, element, attrs) {
                        var model = $parse(attrs.akFileModel);
                        var modelSetter = model.assign;
                        element.bind("change", function() {
                            scope.$apply(function() {
                                modelSetter(scope, element[0].files[0]);
                            });
                        });
                    }
                };
            }
        ]);
})(window, document);
                <html>

               <head>
                  <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
               </head>

               <body ng-app = "myApp">

                  <div ng-controller = "myCtrl">
                     <input type = "file" file-model = "myFile"/>
                     <button ng-click = "uploadFile()">upload me</button>
                  </div>

                  <script>
                     var myApp = angular.module('myApp', []);

                     myApp.directive('fileModel', ['$parse', function ($parse) {
                        return {
                           restrict: 'A',
                           link: function(scope, element, attrs) {
                              var model = $parse(attrs.fileModel);
                              var modelSetter = model.assign;

                              element.bind('change', function(){
                                 scope.$apply(function(){
                                    modelSetter(scope, element[0].files[0]);
                                 });
                              });
                           }
                        };
                     }]);

                     myApp.service('fileUpload', ['$http', function ($http) {
                        this.uploadFileToUrl = function(file, uploadUrl){
                           var fd = new FormData();
                           fd.append('file', file);

                           $http.post(uploadUrl, fd, {
                              transformRequest: angular.identity,
                              headers: {'Content-Type': undefined}
                           })

                           .success(function(){
                           })

                           .error(function(){
                           });
                        }
                     }]);

                     myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
                        $scope.uploadFile = function(){
                           var file = $scope.myFile;

                           console.log('file is ' );
                           console.dir(file);

                           var uploadUrl = "/fileUpload";
                           fileUpload.uploadFileToUrl(file, uploadUrl);
                        };
                     }]);

                  </script>

               </body>
            </html>
<form>
    <div class="form-group">
                    <label for="myFileField">Select a file: </label> 
                    <input type="file" file-model="myFile" /> <label>File Name:</label> 
                    <input type="text" ng-model="filename"></input>
                </div>
                <button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button>
            </form>
 $scope.uploadFile = function (file1) {
            var file = $scope.myFile;  // this is undefined 
            console.log("My file =" +file1); // you get this 
            // Make http call to upload the file or make service call         
 }