如何使用更少的代码和良好实践以 Angular 形式处理许多订阅
How to deal with many subscriptions in an Angular form with less code and good practices
我有一个 Angular 表单,其中有许多 select 选项,这些 select 选项由订阅管理,但我发现每个订阅都有太多代码。
有人可以建议我减少代码量的好方法吗?
提前致谢!
这里有一个例子:https://github.com/jreategui07/testing-subscriptions-form
模拟服务器运行:mockserver -p 8080 -m mock
this.colorSC = this.catalogueService.getColors().subscribe(
(response: any) => {
console.log(response.body);
this.colorsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.brandSC = this.catalogueService.getSizes().subscribe(
(response: any) => {
console.log(response.body);
this.brandsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.sizeSC = this.catalogueService.getFruits().subscribe(
(response: any) => {
console.log(response.body);
this.sizesData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.fruitSC = this.catalogueService.getColors().subscribe(
(response: any) => {
console.log(response.body);
this.fruitsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
您可以将可观察对象连接到 select 的选项作为可观察对象,并使用异步管道绑定数据
为选项声明 Observables
colorSC$ : Observable<any>;
brandSC$ : Observable<any>;
sizeSC$ : Observable<any>;
fruitSC$ : Observable<any>;
注意:使用接口而不是任何接口我不确定数据类型,所以对于这个答案我使用的是任何接口。你可以定义你的接口并在这里使用它们来声明这些 Observable 变量
您现在可以分配这些可观察值,您可以在
中完成
constructor(private fb: FormBuilder, private catalogueService: CatalogueService) {
this.anyForm = this.fb.group({
color: [''],
brand: [''],
size: [''],
fruit: [''],
});
this.colorSC$ = catalogueService.getColors();
this.brandSC$ = catalogueService.getSizes();
this.sizeSC$ = catalogueService.getFruits();
this.fruitSC$ = catalogueService.getColors();
}
并在您的模板中使用异步管道获取项目,例如:colorSC$ | async
请注意,对代码和描述进行安全检查,以便模板不会出错 item?.code
和 item?.description
<form (ngSubmit)="onSubmit()" [formGroup]="anyForm">
<label>Color:</label>
<select formControlName="color">
<option *ngFor="let item of colorSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Brand:</label>
<select formControlName="brand">
<option *ngFor="let item of brandSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Size:</label>
<select formControlName="size">
<option *ngFor="let item of this.sizeSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Fruit:</label>
<select formControlName="fruit">
<option *ngFor="let item of fruitSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<button type="submit">Ok</button>
</form>
在您的服务中,您不必映射它们,因为您没有做任何有用的事情,您返回的是同样的东西
export class CatalogueService {
requestOptions: any;
constructor(public http: HttpClient) {
const headers = new HttpHeaders({
'Content-Type': 'text/plain; charset=utf-8'
});
this.requestOptions = {headers, observe: 'response'};
}
getColors() {
return this.http.get('http://localhost:8080/getColors', this.requestOptions).pipe(map(res => res.body));
}
getBrands() {
return this.http.get('http://localhost:8080/getBrands', this.requestOptions).pipe(map(res => res.body));
}
getSizes() {
return this.http.get('http://localhost:8080/getSizes', this.requestOptions).pipe(map(res => res.body));
}
getFruits() {
return this.http.get('http://localhost:8080/getFruits', this.requestOptions).pipe(map(res => res.body));
}
}
因此您可以摆脱 ngOnInit 和 ngOnDestroy,因为在这个用例中您不需要它们。最好在构造函数级别连接它,因为它们本身可以在构造函数级别运行
我有一个 Angular 表单,其中有许多 select 选项,这些 select 选项由订阅管理,但我发现每个订阅都有太多代码。
有人可以建议我减少代码量的好方法吗?
提前致谢!
这里有一个例子:https://github.com/jreategui07/testing-subscriptions-form
模拟服务器运行:mockserver -p 8080 -m mock
this.colorSC = this.catalogueService.getColors().subscribe(
(response: any) => {
console.log(response.body);
this.colorsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.brandSC = this.catalogueService.getSizes().subscribe(
(response: any) => {
console.log(response.body);
this.brandsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.sizeSC = this.catalogueService.getFruits().subscribe(
(response: any) => {
console.log(response.body);
this.sizesData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
this.fruitSC = this.catalogueService.getColors().subscribe(
(response: any) => {
console.log(response.body);
this.fruitsData = response.body;
},
error =>
{
console.warn('Error', error);
}
);
您可以将可观察对象连接到 select 的选项作为可观察对象,并使用异步管道绑定数据
为选项声明 Observables
colorSC$ : Observable<any>;
brandSC$ : Observable<any>;
sizeSC$ : Observable<any>;
fruitSC$ : Observable<any>;
注意:使用接口而不是任何接口我不确定数据类型,所以对于这个答案我使用的是任何接口。你可以定义你的接口并在这里使用它们来声明这些 Observable 变量
您现在可以分配这些可观察值,您可以在
中完成constructor(private fb: FormBuilder, private catalogueService: CatalogueService) {
this.anyForm = this.fb.group({
color: [''],
brand: [''],
size: [''],
fruit: [''],
});
this.colorSC$ = catalogueService.getColors();
this.brandSC$ = catalogueService.getSizes();
this.sizeSC$ = catalogueService.getFruits();
this.fruitSC$ = catalogueService.getColors();
}
并在您的模板中使用异步管道获取项目,例如:colorSC$ | async
请注意,对代码和描述进行安全检查,以便模板不会出错 item?.code
和 item?.description
<form (ngSubmit)="onSubmit()" [formGroup]="anyForm">
<label>Color:</label>
<select formControlName="color">
<option *ngFor="let item of colorSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Brand:</label>
<select formControlName="brand">
<option *ngFor="let item of brandSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Size:</label>
<select formControlName="size">
<option *ngFor="let item of this.sizeSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<label>Fruit:</label>
<select formControlName="fruit">
<option *ngFor="let item of fruitSC$ | async" [value]="item?.code">{{ item?.description }}</option>
</select>
<br><br>
<button type="submit">Ok</button>
</form>
在您的服务中,您不必映射它们,因为您没有做任何有用的事情,您返回的是同样的东西
export class CatalogueService {
requestOptions: any;
constructor(public http: HttpClient) {
const headers = new HttpHeaders({
'Content-Type': 'text/plain; charset=utf-8'
});
this.requestOptions = {headers, observe: 'response'};
}
getColors() {
return this.http.get('http://localhost:8080/getColors', this.requestOptions).pipe(map(res => res.body));
}
getBrands() {
return this.http.get('http://localhost:8080/getBrands', this.requestOptions).pipe(map(res => res.body));
}
getSizes() {
return this.http.get('http://localhost:8080/getSizes', this.requestOptions).pipe(map(res => res.body));
}
getFruits() {
return this.http.get('http://localhost:8080/getFruits', this.requestOptions).pipe(map(res => res.body));
}
}
因此您可以摆脱 ngOnInit 和 ngOnDestroy,因为在这个用例中您不需要它们。最好在构造函数级别连接它,因为它们本身可以在构造函数级别运行