将表单数据和图像从 HTML 页面绑定到 Angular 控制器

Posted

技术标签:

【中文标题】将表单数据和图像从 HTML 页面绑定到 Angular 控制器【英文标题】:Binding form-data along with image from HTML page to Angular Controller 【发布时间】:2018-01-17 18:16:14 【问题描述】:

我正在尝试将 html 页面中的 form-data 与图像 绑定到 Angular Controller,然后将 form-data 与图像数据一起附加,最后将数据 POST 到API。 所以我搜索并知道,遗憾的是 AngularJs 没有任何图像文件指令。 所以我得到的最终解决方案是创建一个自定义指令,将表单数据附加到图像,然后将该数据发布到服务器。 我尝试了什么: HTML

<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text"  ng-model="UserName" required="required">
<input type="text"  ng-model="FirstName" required="required">
<input type="file"  ng-model="Image" required="required">
<button type="submit" ng-click="product()">save</button>
</form>

自定义指令:

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]);
                );
            );
        
    ;
]);

POST 方法:

scope.product = function() 
     var pro = $scope.pro;
     console.log('Form Data : ' + pro);
    var fd = new FormData();
    angular.forEach($scope.Image, function(file) 
        fd.append('file', file);
    );
    fd.append('pro', JSON.stringify($scope.product));
    $http.post('/products/createProduct', fd, 
            transformRequest: angular.identity,
            headers: 
                'Content-type': undefined
            
        )
        .then(function(data) 
            $scope.ListProducts = data;
            console.log($scope.ListProducts );
        );


但问题是,控制器没有绑定任何东西,而且每次我的对象都是空的。 我什至尝试将数据记录到控制台,但没有得到任何内部数据。 我不知道我做错了什么。 请帮忙..


更新

我能够绑定数据,但是在发布图像路径和其他表单数据时,我得到了所有的空值。

angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config":"method":"POST","transfor‌​mRequest":[null]," tr‌​ansformResponse":[nu‌​ll],"jsonpCallbackPa‌​ram":"callback","url‌​":"/products/createP‌​roduct","data":"pro‌​ductStock":["price "‌​:"","color":""],"pr‌​oductThumbnail":"0"‌​:,"headers":"Ac‌​cept":"application/j‌​儿子, text/plain, /","Content-Type":"application/json;charset=utf-8","status‌​Text":"" 错误

【问题讨论】:

请记住,使用 FormData API 上传图像效率不高,因为 base64 encoding 会增加 33% 的额外开销。考虑直接上传文件并使用url parameters 获取更多数据。 @georgeawg:我该怎么做? -1 状态通常意味着CORS problem。浏览器阻止了 XHR,因为它违反了Same Origin Policy。 AngularJS No 'Access-Control-Allow-Origin' header 可能重复,How to enable CORS in AngularJs 可能重复,Angular HTTP: Status -1 and CORS 可能重复等 – georgeawg 5 小时前 【参考方案1】:

我对您的代码进行了改进。基本上你使用的是 ng-model,而不是像你的指令所说的 file-model,如果只有一个文件,fd.append 文件也不需要迭代。检查代码和plnkr。

控制器

$scope.product = function() 
     var pro = $scope.pro;
     var fd = new FormData();

    fd.append('file', $scope.form.Image);
    fd.append('pro', JSON.stringify($scope.form));
    $http.post('/products/createProduct', fd, 
            transformRequest: angular.identity,
            headers: 
                'Content-type': undefined
            
        )
        .then(function(data) 
            $scope.ListProducts = data;
            console.log($scope.ListProducts );
        );
  ;

HTML

<form role="form" enctype="multipart/form-data" name="myForm">
    <input type="text"  ng-model="form.UserName" required="required">
    <input type="text"  ng-model="form.FirstName" required="required">
    <input type="file" file-model="form.Image" required="required">
    <button type="submit" ng-click="product()">save</button>
</form>

form.Image.name

PLNKR EXAMPLE

**更新**

在网络上可以看到这个。发送数据时。

【讨论】:

感谢您的回答。我能够绑定数据,但是在发布图像路径以及其他表单数据时,我得到了所有的空值。 在浏览器开发者控制台的网络选项卡中,您可以检查数据是否正在发送到 api,以及数据名称如何。 formdata sendint 必须将一个名称文件拆分为另一个 pro 如果 api 是 php $_FILE('file'); 刚刚我签入 network-tab ,我得到了空值。【参考方案2】:

&lt;input type=file&gt; 元素默认情况下不适用于ng-model directive。它需要一个custom directive:

ng-model 一起使用的“files-input”指令的工作演示

angular.module("app",[]);

angular.module("app").directive("filesInput", function() 
  return 
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) 
      elem.on("change", function(e) 
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      )
    
  
);
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" files-input ng-model="fileArray" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileArray">
      file.name
    </div>
  </body>

感谢您的回答。我试过你的代码,得到:

angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config":"method":"POST","transfor‌​mRequest":[null]," tr‌​ansformResponse":[nu‌​ll],"jsonpCallbackPa‌​ram":"callback","url‌​":"/products/createP‌​roduct","data":"pro‌​ductStock":["price "‌​:"","color":""],"pr‌​oductThumbnail":"0"‌​:,"headers":"Ac‌​cept":"application/j‌​儿子, text/plain, /","Content-Type":"application/json;charset=utf-8","status‌​Text":"" 错误

根据我的经验,-1 状态最常见的原因是浏览器因违反 Same Origin Policy. 而阻止了响应

出于安全原因,浏览器会限制从脚本中发起的跨域 HTTP 请求。例如,XMLHttpRequest 和 Fetch 跟在 same-origin policy 后面。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向自己的域发出 HTTP 请求。为了改进 Web 应用程序,开发人员要求浏览器供应商允许跨域请求。

跨域资源共享 (CORS) 机制为 Web 服务器提供跨域访问控制,从而实现安全的跨域数据传输。现代浏览器在 API 容器中使用 CORS(例如 XMLHttpRequest 或 Fetch)来降低跨域 HTTP 请求的风险。

见Use CORS to allow cross-origin access.

【讨论】:

感谢您的回答。我尝试了您的代码,得到 angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config": "method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/products/createProduct","data":" productStock":["price":"","color":""],"productThumbnail":"0":,"headers":"Accept":"application/json, text /plain, /","Content-Type":"application/json;charset=utf-8","statusText":"" 错误 哦,好吧。如果我使用&lt;input type="file" files-input ng-model="product.productThumbnail" multiple&gt;,那么只有我得到上述错误。但如果我使用&lt;input type="file" files-input ng-model="fileArray" multiple&gt;,则没有错误,但该图像名称未存储在数据库。 我在 network-tab:productThumbnail: name: 0: 中得到这个值,你可以看到没有图像名称。

以上是关于将表单数据和图像从 HTML 页面绑定到 Angular 控制器的主要内容,如果未能解决你的问题,请参考以下文章

数据绑定和表单标签库

如何在Python框架Flask中将图像文件从表单上传到数据库

将图像添加到树视图控件 xamarin 表单中

Knockout JS 如何将数据绑定到静态表单元素

Django:无法将上传的图像绑定到表单 ImageField()

AngularJS:将数据绑定到动态创建的 HTML