首页 > 解决方案 > 如何解决Angular7中“由于表单未连接而取消表单提交”?

问题描述

我在 Angular 7 中有一个“create-profile.component.html”,其中包含一个带有 4 个文本输入字段、一个图像选择器按钮和一个提交按钮的表单。提交按钮是唯一一个 type="submit" 的按钮。

我正在使用“profiles.service.ts”来设置函数来处理我在“create-profile.component.ts”中注入和调用的 crud 任务。我还使用 FormGroup 来处理输入。

问题是这样的:

https://i.imgur.com/xF2yOeZ.png

我查看了错误指向的“create-profile.component.ts”内部,但没有发现任何问题。由于构造函数内部的profilesService,函数addProfile()被注入到组件中。此外,profilesService 首先包含 addProfile() 函数。在 html 标记上,我看不到任何问题。

创建-profile.component.ts

export class CreateProfileComponent implements OnInit, OnDestroy {
  profile: Profile;
  isLoading = false;
  form: FormGroup;
  profileImagePreview: string;
  private mode = 'create';
  private profileId: string;
  private authStatusSub: Subscription;

  constructor(
    private profilesService: ProfilesService,
    public route: ActivatedRoute,
    private authService: AuthService
  ) {}

  ngOnInit() {
    this.authStatusSub = this.authService
      .getAuthStatusListener()
      .subscribe(authStatus => {
        this.isLoading = false;
      });
    this.form = new FormGroup({
      name: new FormControl(null, {
        validators: [Validators.required, Validators.minLength(1)]
      }),
      username: new FormControl(null, {
        validators: [Validators.required, Validators.minLength(1)]
      }),
      bio: new FormControl(null, {
        validators: [Validators.required]
      }),
      profileImage: new FormControl(null, {
        validators: [Validators.required],
        asyncValidators: [mimeType]
      }),
    });
    this.route.paramMap.subscribe((paramMap: ParamMap) => {
      if (paramMap.has('profileId')) {
        this.mode = 'edit';
        this.profileId = paramMap.get('profileId');
        this.isLoading = true;
        this.profilesService.getProfile(this.profileId).subscribe(profileData => {
          this.isLoading = false;
          this.profile = {
            id: profileData._id,
            name: profileData.name,
            username: profileData.username,
            bio: profileData.bio,
            profileImage: profileData.profileImage,
            creator: profileData.creator
          };
          this.form.setValue({
            name: this.profile.name,
            username: this.profile.username,
            bio: this.profile.bio,
            profileImage: this.profile.profileImage,
          });
        });
      } else {
        this.mode = 'create';
        this.profileId = null;
      }
    });
  }

  onProfileImagePicked(event: Event) {
    const file = (event.target as HTMLInputElement).files[0];
    this.form.patchValue({ profileImage: file });
    this.form.get('profileImage').updateValueAndValidity();
    const reader = new FileReader();
    reader.onload = () => {
      ////////////////// 'as string' could be removed;
      this.profileImagePreview = reader.result as string;
    };
    reader.readAsDataURL(file);
  }

  onSaveProfile() {
    if (this.form.invalid) {
      return;
    }
    this.isLoading = true;
    if (this.mode === 'create') {
      this.profilesService.addProfile(
        this.form.value.name,
        this.form.value.username,
        this.form.value.bio,
        this.form.value.profileImage,
      );
    } else {
      this.profilesService.updateProfile(
        this.profileId,
        this.form.value.name,
        this.form.value.username,
        this.form.value.bio,
        this.form.value.profileImage,
      );
    }
    this.form.reset();
  }

  ngOnDestroy() {
    this.authStatusSub.unsubscribe();
  }

}

配置文件.service.ts

@Injectable({
  providedIn: 'root'
})
export class ProfilesService {
  private profiles: Profile[] = [];
  private profilesUpdated = new Subject<{ profiles: Profile[] }>();

  constructor(private http: HttpClient, private router: Router) { }

  addProfile(name: string, username: string, bio: string, profileImage: 
  File) {
    const profileData = new FormData();
    profileData.append('name', name);
    profileData.append('username', username);
    profileData.append('bio', bio);
    profileData.append('profileImage', profileImage);
    this.http
      .post<{ message: string; profile: Profile; }>(
        'http://localhost:3000/api/profiles/',
        profileData
      )
      .subscribe(responseData => {
        this.router.navigate(['/']);
      });
  }

创建-profile.component.html

<mat-card class="mat-elevation-z0 card-border">
  <mat-spinner *ngIf="isLoading"></mat-spinner>
  <form [formGroup]="form" (submit)="onSaveProfile()" *ngIf="!isLoading">
    <mat-form-field>
      <input
        matInput
        type="text"
        formControlName="name"
        placeholder="Full Name">
      <mat-error *ngIf="form.get('name').invalid">Please enter a valid name.</mat-error>
    </mat-form-field>
    <mat-form-field>
      <input
        matInput
        type="text"
        formControlName="username"
        placeholder="Username">
      <mat-error *ngIf="form.get('username').invalid">Please enter a valid username.</mat-error>
    </mat-form-field>
    <mat-form-field>
      <textarea
        matInput
        rows="4"
        type="text"
        formControlName="bio"
        placeholder="Bio"></textarea>
      <mat-error *ngIf="form.get('bio').invalid">Please enter a few words about yourself.</mat-error>
    </mat-form-field>
    <div class="porofile-create-buttons-holder">
      <button mat-stroked-button type="button" (click)="profileImagePicker.click()">Choose Profile Image</button>
      <input type="file" #profileImagePicker (change)="onProfileImagePicked($event)">
      <span class="spacer"></span>
      <button mat-stroked-button type="submit">Save Profile</button>
    </div>
    <div class="profile-image-preview" *ngIf="profileImagePreview !== '' && profileImagePreview && form.get('profileImage').valid">
      <img [src]="profileImagePreview" [alt]="form.value.username">
    </div>
  </form>
</mat-card>

我希望没有错误。我有一个字面上相似的组件和服务为“帖子”做同样的事情并且工作得很好。

标签: angular7

解决方案


问题是我的快递后端的“配置文件”控制器内的小写大写大写错误。我不得不重新检查服务器上与“配置文件”相关的所有代码才能弄清楚这一点。


推荐阅读