angular7 - 如何解决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>
我希望没有错误。我有一个字面上相似的组件和服务为“帖子”做同样的事情并且工作得很好。
解决方案
问题是我的快递后端的“配置文件”控制器内的小写大写大写错误。我不得不重新检查服务器上与“配置文件”相关的所有代码才能弄清楚这一点。
推荐阅读
- css - 样式表更改后 Chrome 66+ SVG 不更新颜色
- php - PHP嵌套包含在批处理php过程中
- sharepoint - 如何在 SPFx 中使用本地化资源?
- mysql - 出现错误无法执行语句:由于 BINLOG_FORMAT = STATEMENT 无法写入二进制日志
- c# - Task.Delay vs Thread.Sleep 用于暂停 System.Timers.Timer 的工作
- watson-conversation - 如何在沃森助手(对话)上不混淆地在对话之间跳转?
- javascript - 使 Meteor 子文档具有响应性
- postgresql - 如何在postgres中返回x标准差的中位数和值
- firebase - Firebase:验证电子邮件在几次后停止发送
- python - 如何创建动态棉花糖字段(也就是以编程方式更改用于序列化的字段)?