繁体   English   中英

Angular File Upload指令不更新控制器模型

[英]Angular File Upload directive not updating controller model

我试图遵循这个[教程],但无法让它工作。

我的Angular控制器正在为我的指令中创建的模型记录undefined 这是一个[JSFiddle]的工作创建了我的教程作者。

问题是视图可以找到$scope.myFile但控制器没有( $scope.myFile undefined )。

视图显示{{ myFile.name }} (仅作为示例my-image.jpg )。 myFile变量是一个包含所选文件数据的JS对象。 这很好用。 该指令似乎是为模型分配所选文件的值(因此在视图中正确显示它)。

<input file-model="myFile" type="file"/ >
<div class="label label-info">
  {{ myFile.name }}
</div>
<button ng-click="uploadDocs()">Click</button>

这是我从这个[教程]得到的指令。

由于输入类型file不能使用ng-model ,因此该指令将模型设置为与file输入关联,并在每次文件触发change事件时为其分配。

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(){
              if (element[0].files.length > 1) {
                modelSetter(scope, element[0].files);
              }
              else {
                modelSetter(scope, element[0].files[0]);
              }
            });
          });
        }
      };
    }
  ]).

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

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

有人能告诉我为什么视图会收到$scope.myFile但控制器是否为$scope.myFile记录undefined

我在尝试从控制器访问指令变量时遇到了同样的问题。 在我的情况下,我可以让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);
};

在几个Angular版本中可以看到此问题,其中file对象无法设置范围变量。 作为一个解决方法,将字段传递给控制器​​,使用此文件对象上传(而不是从范围)

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         
 }

希望这能解决问题

我已经看过该教程但是选择使用这个库使得文件无缝上传: ng-file-upload

尝试以下解决方案: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>

服务代码:

    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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM