0

我想使用 ng-repeat 从动态生成的 HTML 表单上传图像文件。我正在使用 ng-file-upload 模块上传单个图像文件(https://github.com/danialfarid/ng-file-upload)。当我从静态 HTML 上传文件时,它工作正常。但是当我尝试从动态生成的 HTML 上传文件时,它不会按预期工作。该文件未上传,并且在 Firefox 控制台中也出现错误,如下所示:

Error: Argument 2 of FormData.append is not an object.

如果我们将文件控制集的 ng-model 设置为 null,则表单提交成功。例如; 如果

<input name='img' type='file' value='' ng-model='data.imageFile' 'ngf-select' accept='image/*' />

$scope.data.imageFile = null;

然后其他参数将由 HTTP 服务提交并正常存储到数据库,但文件不会上传。

在这种动态生成的 HTML 的情况下,有什么方法可以将文件对象分配给 input[type=file] 吗?

代码PLUNKER在这里创建

http://plnkr.co/edit/S7hnVJnuDjWUMQ6PYewk?p=preview

4

1 回答 1

2

是的,有一种方法可以将输入类型=文件分配给动态生成的 html。不仅在页面加载时动态生成,而且在通过 angular 添加新的输入 type=file 时动态生成。我刚做了这个,它奏效了!!!我很兴奋我在这里发布了所有的技巧。作为回报,我所要求的只是当你让它在你的解决方案中工作时请投票。问题和答案现在都在 0 点,但我可以证明这是一个可行的解决方案。

     <input type="file" class="form form-control" placeholder="Section Image" file-model2="fileUploadFile2[getImageIndex(c.ChapterNbr, $index)][$index]" />

请注意,有二维数组,并且这个 input=file 进入 ng-repeat 内的 ng-repeat,当用户按下 +Add 按钮时动态添加。

在角度方面,在 getImageIndex 中:

        var chIndex = 0;
        var sIndex = 0;

        $scope.getImageIndex = function (chNbr, sectionNbr) {
            for (var i = 0; i < $scope.chapters.length; i++) {
                if ($scope.chapters[i].ChapterNbr == chNbr) {
                    chIndex = i;
                    sIndex = sectionNbr;
                    return i;
                };
            };
        };

这纯粹是为了获取索引(第一和第二维,特定于我的设置)。我使用在 StackOverflow 中某个地方发布的指令,我很感谢,以实际获取文件字节和信息,它是这样的:

       .directive('fileModel2', ['$parse', function ($parse) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.bind('change', function (e) {
                    $parse(attrs.fileModel2)
                    .assign(scope, element[0].files[0]);
                    scope.$apply();
                    scope.getFile2(scope.$eval(attrs.indexNumber));
                });
            }
        };
    }])
    .factory('fileReaderFactory', function ($q, $log) {
        return {
            onLoad: function (reader, deferred, scope) {
                return function () {
                    scope.$apply(function () {
                        deferred.resolve(reader.result);
                    });
                };
            },
            onError: function (reader, deferred, scope) {
                return function () {
                    scope.$apply(function () {
                        deferred.reject(reader.result);
                    });
                };
            },
            onProgress: function (reader, scope) {
                return function (event) {
                    scope.$broadcast("fileProgress",
                        {
                            total: event.total,
                            loaded: event.loaded
                        });
                };
            },
            getReader: function (deferred, scope) {
                var reader = new FileReader();
                reader.onload = this.onLoad(reader, deferred, scope);
                reader.onerror = this.onError(reader, deferred, scope);
                reader.onprogress = this.onProgress(reader, scope);
                return reader;
            },

            readAsDataURL: function (file, scope) {
                var deferred = $q.defer();

                var reader = this.getReader(deferred, scope);
                reader.readAsDataURL(file);

                return deferred.promise;
            }
        }
    }
    );

该指令触发 getFile2,它执行 Filereader 以读取预览图像的字节。最后,预览图像:

         $scope.getFile2 = function () {
            console.log($scope.fileUploadFile2[chIndex][sIndex]);
            if ($scope.fileUploadFile2[chIndex][sIndex]) {
                fileReaderFactory.readAsDataURL($scope.fileUploadFile2[chIndex][sIndex], $scope)
                    .then(function (result) {
                        $scope.chapters[chIndex].Sections[sIndex].sectionImgPreview = result;
                    });
            }
        };

这是预览图像的html:

     <img ng-if="s.sectionImgPreview" class="img-responsive" ng-src="{{s.sectionImgPreview}}" alt="" onerror="this.src='@Url.Content("~/Content/Images/ToyApp.png")';" />

此时,$scope.fileUploadFile2[chIndex][sIndex] 已准备好发布到后端,在我的例子中,它是一个 C# 控制器,它接受包含课程章节和部分、图像二进制文件和视频、文本的整个 JSON和 html,变成一个复杂的类,该类又将信息存储到数据库模式中。

于 2015-12-21T05:27:16.593 回答