Angular UI 中的双向绑定和映射
Angular two-way binding and mapping in UI
我有一个虚拟问题...(前端完全没有新手)
我正在使用 Angular 4 和 TypeScript 构建一个小型 CRUD 项目,我在其中调用 API 以便根据 id 获取和更新 phone 数字。
我从服务中得到的 phone 号码非常标准,分为 3 个部分:
- 国家代码
- 前
- 实际人数
但在 UI 中,我实际上有两个输入字段 - 一个用于国家代码和预拨一起,第二个用于实际号码。为了形象化这一点,如果我在编辑它时从用户那里得到的 phone 数字是 +445551234567
,我有两个输入字段 +44555
和 1234567
换句话说,我必须在编辑页面的 UI 中将国家代码 + predial 映射到一起,并且当我将更新回调返回到 API 时,我需要能够再次将其映射到 3 个变量。
在理想世界中,我会在我的服务中映射它,但不幸的是,由于其他限制,这是不可能的。
所以我有这些 models/interfaces:
export interface Contacts {
email: string;
phoneNumber: PhoneNumber;
faxNumber: PhoneNumber;
}
export interface PhoneNumber {
countryCode: string;
predial: string;
number: string;
}
然后在我的输入组件中有一个表单:
this.form = new FormGroup({
phoneCountryCodeAndPredial: new ValidatableFormControl(null, [Validators.required]),
phoneNumber: new ValidatableFormControl(null, [Validators.required]),
faxCountryCodeAndPredial: new ValidatableFormControl(null, [Validators.required]),
faxNumber: new ValidatableFormControl(null, [Validators.required]),
email: new ValidatableFormControl(null, [Validators.pattern(/\S+@\S+\.\S+/)])
});
为了简洁起见,在 html 中只是 phone 数字:
<div class="form-group-line">
<input [formControl]="form.controls['phoneCountryCodeAndPredial']" name="countryCodeAndPredial"
class="required"
placeholder="Predial"
[(ngModel)]=contacts.phoneNumber.countryCode/>
<input [formControl]="form.controls['phoneNumber']" name="phoneNumber"
class="required"
placeholder="Phone Number"
[(ngModel)]="contacts.phoneNumber.number"/>
</div>
所以我想要双向数据绑定,这就是我使用 [(ngModel)] banana in the box
的原因,但是我如何在 ngModel 中使用双向数据绑定 + 映射?
我无法制作一个将国家代码和预拨结合在一起并将值传递给 ngModel 的函数。
那么如何在 UI 中进行此映射?什么是好的做法?
您可以拆分 ngModel
绑定:
<text-input [formControl]="form.controls['phoneCountryCodeAndPredial']"
name="countryCodeAndPredial"
class="required"
placeholder="Predial"
[ngModel]="contacts.phoneNumber.countryCode + contacts.phoneNumber.predial"
(ngModelChange)="Utils.setCombinedNumber(contacts.phoneNumber, $event)"
>
然后在模型更改时设置正确的字段:
setCombinedNumber(phoneNumber: PhoneNumber, combined: string) {
// your actual splitting code here
let pattern = new RegExp(/^(\+\d{2})(\d+)$/);
if (pattern.test(combined)) {
let match = pattern.exec(combined);
phoneNumber.countryCode = match[1];
phoneNumber.predial = match[2];
}
else {
// do some error handling here? maybe show a toast?
}
}
我有一个虚拟问题...(前端完全没有新手)
我正在使用 Angular 4 和 TypeScript 构建一个小型 CRUD 项目,我在其中调用 API 以便根据 id 获取和更新 phone 数字。
我从服务中得到的 phone 号码非常标准,分为 3 个部分:
- 国家代码
- 前
- 实际人数
但在 UI 中,我实际上有两个输入字段 - 一个用于国家代码和预拨一起,第二个用于实际号码。为了形象化这一点,如果我在编辑它时从用户那里得到的 phone 数字是 +445551234567
,我有两个输入字段 +44555
和 1234567
换句话说,我必须在编辑页面的 UI 中将国家代码 + predial 映射到一起,并且当我将更新回调返回到 API 时,我需要能够再次将其映射到 3 个变量。
在理想世界中,我会在我的服务中映射它,但不幸的是,由于其他限制,这是不可能的。
所以我有这些 models/interfaces:
export interface Contacts {
email: string;
phoneNumber: PhoneNumber;
faxNumber: PhoneNumber;
}
export interface PhoneNumber {
countryCode: string;
predial: string;
number: string;
}
然后在我的输入组件中有一个表单:
this.form = new FormGroup({
phoneCountryCodeAndPredial: new ValidatableFormControl(null, [Validators.required]),
phoneNumber: new ValidatableFormControl(null, [Validators.required]),
faxCountryCodeAndPredial: new ValidatableFormControl(null, [Validators.required]),
faxNumber: new ValidatableFormControl(null, [Validators.required]),
email: new ValidatableFormControl(null, [Validators.pattern(/\S+@\S+\.\S+/)])
});
为了简洁起见,在 html 中只是 phone 数字:
<div class="form-group-line">
<input [formControl]="form.controls['phoneCountryCodeAndPredial']" name="countryCodeAndPredial"
class="required"
placeholder="Predial"
[(ngModel)]=contacts.phoneNumber.countryCode/>
<input [formControl]="form.controls['phoneNumber']" name="phoneNumber"
class="required"
placeholder="Phone Number"
[(ngModel)]="contacts.phoneNumber.number"/>
</div>
所以我想要双向数据绑定,这就是我使用 [(ngModel)] banana in the box
的原因,但是我如何在 ngModel 中使用双向数据绑定 + 映射?
我无法制作一个将国家代码和预拨结合在一起并将值传递给 ngModel 的函数。
那么如何在 UI 中进行此映射?什么是好的做法?
您可以拆分 ngModel
绑定:
<text-input [formControl]="form.controls['phoneCountryCodeAndPredial']"
name="countryCodeAndPredial"
class="required"
placeholder="Predial"
[ngModel]="contacts.phoneNumber.countryCode + contacts.phoneNumber.predial"
(ngModelChange)="Utils.setCombinedNumber(contacts.phoneNumber, $event)"
>
然后在模型更改时设置正确的字段:
setCombinedNumber(phoneNumber: PhoneNumber, combined: string) {
// your actual splitting code here
let pattern = new RegExp(/^(\+\d{2})(\d+)$/);
if (pattern.test(combined)) {
let match = pattern.exec(combined);
phoneNumber.countryCode = match[1];
phoneNumber.predial = match[2];
}
else {
// do some error handling here? maybe show a toast?
}
}