我想使用 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 的情况下,有什么方法可以将文件对象分配给输入[type=file]?
代码PLUNKER在此处创建
最佳答案
是的,有一种方法可以将输入类型=文件分配给动态生成的 html。不仅在页面加载时动态生成,而且在通过 Angular 添加新的输入类型=文件时也动态生成。我刚刚做了这个并且成功了!!!我很兴奋我在这里发布了所有的技巧。我所要求的返回是,当您让它在您的解决方案中发挥作用时,请投票。现在问题和答案都是 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 按钮时动态添加。
在 Angular 一侧,在 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# Controller ,它接受包含类(class)章节、图像二进制文件和视频、文本和 html 放入一个复杂的类中,该类又将信息存储到数据库模式中。
关于javascript - angularjs - ng-file-upload 未将模型绑定(bind)到动态创建的 HTML 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31696453/