如何在 Angular8 中显示在另一个组件中提交的表单?
How to display forms submit in another component in Angular 8?
我正在学习 Angular 并且我试图在与实际表单不同的组件中显示提交的表单数据。
这就是我设置我的应用程序的方式:我在一个组件中构建了表单,创建了一个用户模型,创建了一个应该提供跨组件交互的服务,并创建了一个输出组件。
结构如下所示:
app-component folder
app.component.html,ts,css; app.module etc. files
home-form.component folder
home-form.component.hmtl,ts,css files
输出组件文件夹
output.component.html,ts,css files
共享文件夹
user-module.ts, user-data.service.ts
到目前为止,这是我的代码:
这是我的用户模型
export class User {
public name: string;
public surname: string;
public gender: string;
public email: string;
constructor(name: string, surname: string, gender: string, email: string) {
this.name = name;
this.surname = surname;
this.gender = gender;
this.email = email;
}
}
HTML 表单组件
<div class="container">
<form class="mt-5" (ngSubmit)="onSubmit()" #myForm="ngForm">
<div class="row d-flex justify-content-center">
<div class="col-md-6">
<label for="name">Name</label>
<input
type="text"
id="name"
class="form-control"
placeholder="start typing here..."
ngModel
name="name"
required
#name="ngModel">
<span class="help-block text-danger" *ngIf="!name.valid && name.touched">*Please, enter a valid name</span>
</div>
<div class="col-md-6">
<label for="surname">Surname</label>
<input
type="text"
id="surname"
class="form-control"
placeholder="start typing here..."
ngModel
name="surname"
required
#surname="ngModel">
<span class="help-block text-danger" *ngIf="!surname.valid && surname.touched">*Please, enter a valid surname</span>
</div>
<div class="col-md-6 mt-2">
<label for="gender">Gender</label>
<div class="form-check form-check-inline d-block">
<input
class="form-check-input"
type="radio"
name="gender"
id="maleGender"
value="male"
ngModel
required>
<label class="form-check-label" for="inlineRadio1">Male</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
id="femaleGender"
value="female"
ngModel
required>
<label class="form-check-label" for="inlineRadio2">Female</label>
</div>
</div>
<div class="col-md-6 mt-2">
<label for="email">E-mail</label>
<input
type="email"
id="email"
class="form-control"
placeholder="start typing here..."
ngModel
name="email"
required
email
#email="ngModel">
<span class="help-block text-danger" *ngIf="!email.valid && email.touched">*Please, enter a valid e-mail</span>
</div>
<div class="mt-5">
<button
type="submit"
class="btn btn-primary"
[disabled]="!myForm.valid">Submit</button>
</div>
</div>
</form>
</div>
该组件的 TS 文件
import { Component, OnInit, ViewChild, } from '@angular/core';
import { userDataService } from '../shared/user-data.service';
import { NgForm } from '@angular/forms';
import { User } from '../shared/user.model';
@Component({
selector: 'app-home-form',
templateUrl: './home-form.component.html',
styleUrls: ['./home-form.component.css'],
providers: [userDataService]
})
export class HomeFormComponent implements OnInit {
@ViewChild('myForm', { static: false }) userForm: NgForm;
constructor(private userData: userDataService) {}
ngOnInit() {}
onSubmit(){
const newUser = new User(this.userForm.value['name'], this.userForm.value['surname'], this.userForm.value['gender'], this.userForm.value['email']);
this.userData.addUser(newUser);
}
}
然后是用户数据服务
import { User } from './user.model';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class userDataService {
private myUser = new Subject<User>();
myUserObservable = this.myUser.asObservable();
addUser(user: User){
this.myUser.next(user);
//console.log(user);
}
}
直到这里我仍然可以使用表单中提交的所有数据记录对象用户。
这是应该输出用户的组件的ts文件。我在这里做错了什么?
import { Component, OnInit, OnDestroy } from '@angular/core';
import { userDataService } from '../shared/user-data.service';
import { User } from '../shared/user.model';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css'],
providers: [userDataService]
})
export class UserProfileComponent implements OnInit, OnDestroy {
user: User;
constructor(private userData: userDataService) {}
ngOnInit() {
this.userData.myUserObservable.subscribe(
(user: User) => {
this.user = user;
console.log(user);
}
);
}
ngOnDestroy(){
}
}
ngOnDestroy 实现取消订阅。
console.log 只是一种测试数据是否到达的方法,我想通过字符串插值来显示数据。类似的东西
<div class="container">
<div class="row">
<div class="col-md-12">
<h3>You've created your profile!</h3>
<p>Name: {{ user.name }}</p>
<p>Surname: {{ user.surname }}</p>
<p>Gender: {{ user.gender }}</p>
<p>E-mail: {{ user.email }}</p>
</div>
</div>
非常感谢任何帮助和建议,因为我真的被困在这里了。
谢谢大家!
问题是您注入了两个不同的 userDataService
实例 - 每个组件一个。
- 从组件装饰器中删除
providers: [userDataService]
。您可以在 Official Angular documentation: Limiting provider scope with components 阅读更多相关信息
因此,您的 Component
装饰器应如下所示:
@Component({
selector: 'app-home-form',
templateUrl: './componentname.html',
styleUrls: ['./componentname.css']
})
userDataService
的 Injactable
装饰器应该如下所示
@Injectable({
providedIn: 'root'
})
export class userDataService {
....
在这种情况下,您的服务将作为单例注入到您的任何组件中 (this injectable should be provided in the 'root' injector, which will be the application-level injector in most apps.)
我正在学习 Angular 并且我试图在与实际表单不同的组件中显示提交的表单数据。
这就是我设置我的应用程序的方式:我在一个组件中构建了表单,创建了一个用户模型,创建了一个应该提供跨组件交互的服务,并创建了一个输出组件。 结构如下所示:
app-component folder
app.component.html,ts,css; app.module etc. files
home-form.component folder
home-form.component.hmtl,ts,css files
输出组件文件夹
output.component.html,ts,css files
共享文件夹
user-module.ts, user-data.service.ts
到目前为止,这是我的代码:
这是我的用户模型
export class User {
public name: string;
public surname: string;
public gender: string;
public email: string;
constructor(name: string, surname: string, gender: string, email: string) {
this.name = name;
this.surname = surname;
this.gender = gender;
this.email = email;
}
}
HTML 表单组件
<div class="container">
<form class="mt-5" (ngSubmit)="onSubmit()" #myForm="ngForm">
<div class="row d-flex justify-content-center">
<div class="col-md-6">
<label for="name">Name</label>
<input
type="text"
id="name"
class="form-control"
placeholder="start typing here..."
ngModel
name="name"
required
#name="ngModel">
<span class="help-block text-danger" *ngIf="!name.valid && name.touched">*Please, enter a valid name</span>
</div>
<div class="col-md-6">
<label for="surname">Surname</label>
<input
type="text"
id="surname"
class="form-control"
placeholder="start typing here..."
ngModel
name="surname"
required
#surname="ngModel">
<span class="help-block text-danger" *ngIf="!surname.valid && surname.touched">*Please, enter a valid surname</span>
</div>
<div class="col-md-6 mt-2">
<label for="gender">Gender</label>
<div class="form-check form-check-inline d-block">
<input
class="form-check-input"
type="radio"
name="gender"
id="maleGender"
value="male"
ngModel
required>
<label class="form-check-label" for="inlineRadio1">Male</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
id="femaleGender"
value="female"
ngModel
required>
<label class="form-check-label" for="inlineRadio2">Female</label>
</div>
</div>
<div class="col-md-6 mt-2">
<label for="email">E-mail</label>
<input
type="email"
id="email"
class="form-control"
placeholder="start typing here..."
ngModel
name="email"
required
email
#email="ngModel">
<span class="help-block text-danger" *ngIf="!email.valid && email.touched">*Please, enter a valid e-mail</span>
</div>
<div class="mt-5">
<button
type="submit"
class="btn btn-primary"
[disabled]="!myForm.valid">Submit</button>
</div>
</div>
</form>
</div>
该组件的 TS 文件
import { Component, OnInit, ViewChild, } from '@angular/core';
import { userDataService } from '../shared/user-data.service';
import { NgForm } from '@angular/forms';
import { User } from '../shared/user.model';
@Component({
selector: 'app-home-form',
templateUrl: './home-form.component.html',
styleUrls: ['./home-form.component.css'],
providers: [userDataService]
})
export class HomeFormComponent implements OnInit {
@ViewChild('myForm', { static: false }) userForm: NgForm;
constructor(private userData: userDataService) {}
ngOnInit() {}
onSubmit(){
const newUser = new User(this.userForm.value['name'], this.userForm.value['surname'], this.userForm.value['gender'], this.userForm.value['email']);
this.userData.addUser(newUser);
}
}
然后是用户数据服务
import { User } from './user.model';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class userDataService {
private myUser = new Subject<User>();
myUserObservable = this.myUser.asObservable();
addUser(user: User){
this.myUser.next(user);
//console.log(user);
}
}
直到这里我仍然可以使用表单中提交的所有数据记录对象用户。
这是应该输出用户的组件的ts文件。我在这里做错了什么?
import { Component, OnInit, OnDestroy } from '@angular/core';
import { userDataService } from '../shared/user-data.service';
import { User } from '../shared/user.model';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css'],
providers: [userDataService]
})
export class UserProfileComponent implements OnInit, OnDestroy {
user: User;
constructor(private userData: userDataService) {}
ngOnInit() {
this.userData.myUserObservable.subscribe(
(user: User) => {
this.user = user;
console.log(user);
}
);
}
ngOnDestroy(){
}
}
ngOnDestroy 实现取消订阅。 console.log 只是一种测试数据是否到达的方法,我想通过字符串插值来显示数据。类似的东西
<div class="container">
<div class="row">
<div class="col-md-12">
<h3>You've created your profile!</h3>
<p>Name: {{ user.name }}</p>
<p>Surname: {{ user.surname }}</p>
<p>Gender: {{ user.gender }}</p>
<p>E-mail: {{ user.email }}</p>
</div>
</div>
非常感谢任何帮助和建议,因为我真的被困在这里了。 谢谢大家!
问题是您注入了两个不同的 userDataService
实例 - 每个组件一个。
- 从组件装饰器中删除
providers: [userDataService]
。您可以在 Official Angular documentation: Limiting provider scope with components 阅读更多相关信息
因此,您的 Component
装饰器应如下所示:
@Component({
selector: 'app-home-form',
templateUrl: './componentname.html',
styleUrls: ['./componentname.css']
})
userDataService
的Injactable
装饰器应该如下所示@Injectable({ providedIn: 'root' }) export class userDataService { ....
在这种情况下,您的服务将作为单例注入到您的任何组件中 (this injectable should be provided in the 'root' injector, which will be the application-level injector in most apps.)