angular 中的适配器模式使用打字稿作为反应形式
Adapter pattern in angular using typescript for a reactive form
我正在寻找有关如何在 angular6 中使用适配器模式的解决方案。我已经阅读了大量文章或教程,但未能掌握其中的概念。请就此分享一些见解。简而言之,我使用服务来获取
一些数据,我需要在组件中使用它,但组件中使用的模型与服务中使用的模型不同。
我需要对其进行编辑并以预期格式发回服务。我怀疑的本质是我们是否需要创建一个接口来处理 http 调用?如果是,我们如何保存数据并在我的适配器 class 中使用它。由于我提到的链接提倡将数据模型和视图模型分开,我很困惑。
下面是服务器返回的json(assets/mocks/quote.json)
{
"quote": {
"quoteId": 123,
"commenseDate": "12/ 15/2018",
"quoteType": "Small",
"count": 10,
"customerInfo": {
"customerName": "ABC",
"address": "xxxx xxx xxx",
"city": "Philadelphia",
"state": "Philadelphia ",
"zip": "xxxxx",
"county": "PA",
"phone": "",
"eligibles": 2,
"employeeCount": 2
}
}
}
我对连接到网络服务时模型和接口的使用感到困惑。在参考 angular 文档后,我知道我们需要使用数据模型的接口,并在连接到 Web 服务时使用该类型。所以我创建了一个接口来处理我的数据模型
export interface Quote{
quoteId: number;
commenseDate: string;
count: number;
quoteType: string;
customerInfo: CustomerInfo
}
export interface CustomerInfo {
customerName: string;
address: string;
city: string;
state: string;
zip: number;
county: string;
phone: number;
eligibles: number;
employeeCount: number;
}
在我的服务电话中我使用了这个 interface.Below 是我的报价搜索-service.ts 文件
export class QuoteSearchListService {
/* ApiService- is just a wrapper class to hold the http logic. This class imports HttpClient and uses its get
* and post methods
*/
constructor(private apiService:ApiService) { }
/** Get a quote item */
getQuoteItem(quoteId:number):Observable<Quote>{
return this.apiService.get<Quote>('assets/mocks/quote.json')
.pipe(map((data) => data));
}
}
我在我的组件中使用反应式表单,我使用如下所示的表单模型
export class QuoteComponent implements OnInit {
private form: FormGroup;
constructor(private router: Router, private fb: FormBuilder, private quoteService: QuoteSearchListService) {
this.form = this.fb.group({
customerName: [null, Validators.required]
address: this.fb.group({
`enter code here`
address1: ['', Validators.required],
address2: ['']
})
addressDetails: this.fb.group({
state: [null, Validators.required],
city: [null, Validators.required],
zip: [null, Validators.required]
}),
county: [''],
phone: ['', [Validators.required, Validators.minLength(10)]],
contact: this.fb.group({
contactFirstName: [null, Validators.required],
contactLastName: [null, Validators.required],
}),
eligibles: [null, Validators.required],
empCount: [null, Validators.required],
fteCount: [null, Validators.required]
})
}
ngOnInit() {
this.getQuoteItem(this.quoteId);
}
getQuoteItem() {
this.quoteService.getQuoteItem(quoteId).subscribe(response => {
this.form.setValue(response.quote);
})
}
}
我的问题如下:
- 如何在这种情况下使用适配器模式,使我的数据模型和表单模型相互独立?
- 我是否需要创建 models/classes 以在除表单模型之外的组件中使用。
例如,请参见表单模型中的 'addressDetails' 与数据模型不同。
- 如何从数据模型转换为表单模型(对于 get 调用),反之亦然(对于 post/put 调用)。我应该写一个额外的服务来来回转换这个模型吗?
我引用的链接:
https://itnext.io/dont-clone-back-end-models-in-angular-f7a749bdc1b0
https://blog.florimondmanca.com/consuming-apis-in-angular-the-model-adapter-pattern
在Javascript中,没有打字。当你的变量被赋值时,或者当对它们执行操作时,它们是动态类型的。
在 Typescript 中,您可以输入变量。但是一旦编译完成,类型就会被删除。它们只是在这里强制执行一些行为预编译,并帮助您进行智能感知。
但是要回答你:
1 - 表单模型应该依赖于数据模型。如果您想编辑信息并将它们发回,它们应该具有相同的结构。
为此,您有两个选择,模板驱动(依赖于您的模型)和反应式(依赖于您所做的实现)形式。在您的情况下,您应该使用模板驱动的方法。
2 - 如果发送的有效载荷与接收到的有效载荷没有区别(模型方面),那么你不应该有不同的模型。所以不,你不应该创建特定于表单的 类 或接口。
3 - 它应该是透明的,你不应该做任何事情。
在我看来,一般来说,form-model 和 data-model 是不同的。所以你需要将表单模型转换为数据模型,反之亦然。
在哪里?如果它是 "simple" 和共同价值,我喜欢在服务中使用。例如我们收到一个字符串格式的日期,我们想要作为日期对象,或者收到一个字符串类型 "London|Madrid" 并且您想转换为数组
service.getList().pipe(map(list=>{
list.forEach(item=>
{
item.date=new Date(item.date); //now "date" is a Date Object
item.cities=item.cities.split('|'); //now cities is an array of Strings
}))
嗯,我们在服务中的saveData变成了这样
saveData(data)
{
data.date=data.date.getFullYear()+"-"+
("0"+(data.date.getMonth()+1)).slice(-2)+"-"+
"0"+(data.date.getDate()).slice(-2)
data.cities=data.cities.join("|");
this.httpClient.post("....",data)
}
如果比较复杂,我更愿意在组件中make
我正在寻找有关如何在 angular6 中使用适配器模式的解决方案。我已经阅读了大量文章或教程,但未能掌握其中的概念。请就此分享一些见解。简而言之,我使用服务来获取 一些数据,我需要在组件中使用它,但组件中使用的模型与服务中使用的模型不同。 我需要对其进行编辑并以预期格式发回服务。我怀疑的本质是我们是否需要创建一个接口来处理 http 调用?如果是,我们如何保存数据并在我的适配器 class 中使用它。由于我提到的链接提倡将数据模型和视图模型分开,我很困惑。
下面是服务器返回的json(assets/mocks/quote.json)
{
"quote": {
"quoteId": 123,
"commenseDate": "12/ 15/2018",
"quoteType": "Small",
"count": 10,
"customerInfo": {
"customerName": "ABC",
"address": "xxxx xxx xxx",
"city": "Philadelphia",
"state": "Philadelphia ",
"zip": "xxxxx",
"county": "PA",
"phone": "",
"eligibles": 2,
"employeeCount": 2
}
}
}
我对连接到网络服务时模型和接口的使用感到困惑。在参考 angular 文档后,我知道我们需要使用数据模型的接口,并在连接到 Web 服务时使用该类型。所以我创建了一个接口来处理我的数据模型
export interface Quote{
quoteId: number;
commenseDate: string;
count: number;
quoteType: string;
customerInfo: CustomerInfo
}
export interface CustomerInfo {
customerName: string;
address: string;
city: string;
state: string;
zip: number;
county: string;
phone: number;
eligibles: number;
employeeCount: number;
}
在我的服务电话中我使用了这个 interface.Below 是我的报价搜索-service.ts 文件
export class QuoteSearchListService {
/* ApiService- is just a wrapper class to hold the http logic. This class imports HttpClient and uses its get
* and post methods
*/
constructor(private apiService:ApiService) { }
/** Get a quote item */
getQuoteItem(quoteId:number):Observable<Quote>{
return this.apiService.get<Quote>('assets/mocks/quote.json')
.pipe(map((data) => data));
}
}
我在我的组件中使用反应式表单,我使用如下所示的表单模型
export class QuoteComponent implements OnInit {
private form: FormGroup;
constructor(private router: Router, private fb: FormBuilder, private quoteService: QuoteSearchListService) {
this.form = this.fb.group({
customerName: [null, Validators.required]
address: this.fb.group({
`enter code here`
address1: ['', Validators.required],
address2: ['']
})
addressDetails: this.fb.group({
state: [null, Validators.required],
city: [null, Validators.required],
zip: [null, Validators.required]
}),
county: [''],
phone: ['', [Validators.required, Validators.minLength(10)]],
contact: this.fb.group({
contactFirstName: [null, Validators.required],
contactLastName: [null, Validators.required],
}),
eligibles: [null, Validators.required],
empCount: [null, Validators.required],
fteCount: [null, Validators.required]
})
}
ngOnInit() {
this.getQuoteItem(this.quoteId);
}
getQuoteItem() {
this.quoteService.getQuoteItem(quoteId).subscribe(response => {
this.form.setValue(response.quote);
})
}
}
我的问题如下:
- 如何在这种情况下使用适配器模式,使我的数据模型和表单模型相互独立?
- 我是否需要创建 models/classes 以在除表单模型之外的组件中使用。 例如,请参见表单模型中的 'addressDetails' 与数据模型不同。
- 如何从数据模型转换为表单模型(对于 get 调用),反之亦然(对于 post/put 调用)。我应该写一个额外的服务来来回转换这个模型吗?
我引用的链接: https://itnext.io/dont-clone-back-end-models-in-angular-f7a749bdc1b0
https://blog.florimondmanca.com/consuming-apis-in-angular-the-model-adapter-pattern
在Javascript中,没有打字。当你的变量被赋值时,或者当对它们执行操作时,它们是动态类型的。
在 Typescript 中,您可以输入变量。但是一旦编译完成,类型就会被删除。它们只是在这里强制执行一些行为预编译,并帮助您进行智能感知。
但是要回答你:
1 - 表单模型应该依赖于数据模型。如果您想编辑信息并将它们发回,它们应该具有相同的结构。
为此,您有两个选择,模板驱动(依赖于您的模型)和反应式(依赖于您所做的实现)形式。在您的情况下,您应该使用模板驱动的方法。
2 - 如果发送的有效载荷与接收到的有效载荷没有区别(模型方面),那么你不应该有不同的模型。所以不,你不应该创建特定于表单的 类 或接口。
3 - 它应该是透明的,你不应该做任何事情。
在我看来,一般来说,form-model 和 data-model 是不同的。所以你需要将表单模型转换为数据模型,反之亦然。
在哪里?如果它是 "simple" 和共同价值,我喜欢在服务中使用。例如我们收到一个字符串格式的日期,我们想要作为日期对象,或者收到一个字符串类型 "London|Madrid" 并且您想转换为数组
service.getList().pipe(map(list=>{
list.forEach(item=>
{
item.date=new Date(item.date); //now "date" is a Date Object
item.cities=item.cities.split('|'); //now cities is an array of Strings
}))
嗯,我们在服务中的saveData变成了这样
saveData(data)
{
data.date=data.date.getFullYear()+"-"+
("0"+(data.date.getMonth()+1)).slice(-2)+"-"+
"0"+(data.date.getDate()).slice(-2)
data.cities=data.cities.join("|");
this.httpClient.post("....",data)
}
如果比较复杂,我更愿意在组件中make