【问题标题】:How to include a file upload control in an Angular2 reactive form?如何在 Angular2 反应形式中包含文件上传控件?
【发布时间】:2017-09-12 15:44:12
【问题描述】:

由于某些奇怪的原因,在线上没有教程或代码示例展示如何使用 Angular2 响应式表单,而不仅仅是简单的输入或选择下拉菜单。

我需要创建一个表单来让用户选择他们的头像。 (图片文件)

以下不起作用。 (即 Avatar 属性从不显示任何值更改。)

profile.component.html:

               <form [formGroup]="profileForm" novalidate>
                 
                        <div class="row">
                            <div class="col-md-4 ">
                                <img src="{{imgUrl}}uploads/avatars/{{getUserAvatar}}" style="width:150px; height:150px;float:left;border-radius:50%;margin-right:25px;margin-left:10px;">

                                <div class="form-group">
                                    <label>Update Profile Image</label>
                                    <input class="form-control" type="file" formControlName="avatar">
                                </div>
                            </div>
                            <div class="col-md-8 ">
                                <div class="form-group">
                                    <label >Firstname:
                                        <input class="form-control" formControlName="firstname">
                                    </label>
                                </div>
                                <div class="form-group">
                                    <label >Lastname:
                                        <input class="form-control" formControlName="lastname">
                                    </label>
                                </div>
                                <div class="form-group">
                                    <label >Email:
                                        <input class="form-control" formControlName="email">
                                    </label>
                                </div>
                                <div class="form-group">
                                    <label >Password:
                                        <input class="form-control" type="password" formControlName="password">
                                    </label>
                                </div>
                            </div>
                        </div>
                 
                </form>
                <p>Form value: {{ profileForm.value | json }}</p>
                <p>Form status: {{ profileForm.status | json }}</p>

profile.component.ts:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup,  Validators } from '@angular/forms';
import {Config} from '../../services/config.service';
import {AuthService} from '../../services/auth.service';
import {User} from '../../models/user.model';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
  
  authUser:User;

  profileForm : FormGroup; 

  constructor(private authService:AuthService, private fb: FormBuilder) {}
          
  createForm() {
    this.profileForm = this.fb.group({
      firstname:  [this.authUser.firstname, Validators.required ],
      lastname: [this.authUser.lastname, Validators.required ],
      email: [this.authUser.email, Validators.required ],
      avatar: [this.authUser.avatar, Validators.required ],
      password:['xxxxxx', Validators.minLength(4)] 
    });
  }
  ngOnInit() {
    this.authUser = this.authService.getAuthUser();

    this.createForm();
  } 

【问题讨论】:

  • 你都是其他价值观吗?

标签: file-upload angular2-forms


【解决方案1】:

您可以使用以下方法上传任何形式的图片。

向您的控件公开一种更改方法。

<input class="form-control" type="file" name="avatar" (change)="imageUpload($event)">
<img [src]="imageUrl" />

在您的类中添加以下逻辑。

 // Declare the variable. 
  imageUrl: any;

   //method definition in your class 
    imageUpload(e) {
        let reader = new FileReader();
        //get the selected file from event
        let file = e.target.files[0];
        reader.onloadend = () => {
          //Assign the result to variable for setting the src of image element
          this.imageUrl = reader.result;
        }
        reader.readAsDataURL(file);
      }
    }

上传图片后,您可以使用 this.imageUrl 更新表单模型。 要将图像或文件上传到服务器,您可以从以下链接中获取参考。

How to upload file in Angular2

如果此解决方案适合您,请告诉我。

【讨论】:

  • 已经尝试使这项工作 2 天了,我可以确认它不能... Http 现在可以发送文件,但这不是这样做的方法。 (见devblog.dymel.pl/2016/09/02/…
  • 如何验证 2 mb 的输入类型文件,例如,如果文件超过 2mb,我不会让用户点击提交。可以举个例子吗
  • @JoeSleiman 您可以在将 reader.result 分配给 imageUrl 之前检查 file.size > 1048576*2 如果是,则分配 reader.result 否则向用户显示相关错误消息。
  • @RahulRai 请参考此链接了解我的问题:stackoverflow.com/questions/43781998/…
【解决方案2】:

可以在这里找到简单的答案。 https://devblog.dymel.pl/2016/09/02/upload-file-image-angular2-aspnetcore/

HTML

    <input #fileInput type="file"/>
    <button (click)="addFile()">Add</button>

组件.ts

@ViewChild("fileInput") fileInput;

addFile(): void {
let fi = this.fileInput.nativeElement;
if (fi.files && fi.files[0]) {
    let fileToUpload = fi.files[0];
    this.uploadService
        .upload(fileToUpload)
        .subscribe(res => {
            console.log(res);
        });
    }
}

服务.ts

upload(fileToUpload: any) {
    let input = new FormData();
    input.append("file", fileToUpload);

    return this.http.post("/api/uploadFile", input);
}

【讨论】:

  • 可以,但是如果输入能参与表单验证机制就好了。
  • @JoeSleiman 问题是针对反应形式的。所以可能还有其他字段,而不仅仅是文件上传字段。在这种情况下,最好在提交时验证表单,而不是在客户端上传时验证,因为
  • 同意。这个答案绕过了整个 Reactive From 概念。使用响应式,您不应该从组件(即@ViewChild)访问模板
  • 看起来 Angular 中没有(也不会)对 &lt;input type="file"&gt; 的任何支持:github.com/angular/angular.io/issues/3466 Odd...
  • @JoeSleiman 为什么要单独发送(发布)图像而不是在表单中。我正在尝试将整个表格与两张图片一起发布。这样处理(在服务器上)会更难。
【解决方案3】:

我对此有点晚了,但是对于可能来到这里寻找相同解决方案的其他任何人 - 这是我的 file input accessor,可用于反应式或模板驱动的表单。演示here

它提供了一些可选的验证,可用于检查图像尺寸和文件大小、扩展名、类型,默认情况下禁用。

npm i file-input-accessor 并将模块添加到您的 AppModule 导入中:

import {BrowserModule} from '@angular/platform-browser';
import {FileInputAccessorModule} from "file-input-accessor";

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        FileInputAccessorModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {}

然后像使用任何其他输入一样使用您的文件输入:

<!--Reactive Forms-->
<input type="file" multiple [formControl]="someFileControl" />
<input type="file" multiple formControlName="someFileControl" />

<!--Template-driven-->
<input type="file" name="file-input" multiple [(ngModel)]="fileList" />

您可以像订阅任何其他反应式控件一样订阅 valueChanges 属性。

【讨论】:

  • 我想看看如何将它与实际文件上传到服务器一起使用。目前正在查看此内容以了解如何实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
  • 2017-11-02
  • 1970-01-01
相关资源
最近更新 更多