简体   繁体   English

UI 中的 Angular 双向绑定和映射

[英]Angular two-way binding and mapping in UI

I have a dummy question... (complete noobie on frontend side)我有一个虚拟的问题......(前端的完全noobie)

I am building a small CRUD project with Angular 4 and TypeScript where I make calls to an API in order to get and update phone numbers based on an id.我正在使用 Angular 4 和 TypeScript 构建一个小型 CRUD 项目,我在其中调用 API 以获取和更新基于 id 的电话号码。

The phone number which I get from the service is pretty standard and divided in 3 parts:我从服务中获得的电话号码非常标准,分为 3 部分:

  1. country code国家代码
  2. predial预拨号
  3. actual number实际人数

But in the UI, I have actually two input fields - one for country code and predial together and a second one for the actual number.但在 UI 中,我实际上有两个输入字段 - 一个用于国家代码和预拨号,第二个用于实际号码。 To visualize this, if the phone number I get from user is +445551234567 when I am editing it, I have two input fields with +44555 and 1234567为了形象化这一点,如果我在编辑时从用户那里得到的电话号码是+445551234567 ,我有两个输入字段,分别是+445551234567

In other words, I have to map the country code + predial together in the UI in my edit page and also when I make the update call back to the API, I need to be able to map it again to 3 variables.换句话说,我必须在编辑页面的 UI 中将国家/地区代码 + predial 映射到一起,并且当我将更新调用返回到 API 时,我需要能够再次将其映射到 3 个变量。

In ideal world, I would map this in my service, but that's unfortunately not possible due to other restrictions.在理想的世界中,我会在我的服务中映射它,但不幸的是,由于其他限制,这是不可能的。

So I have these models/interfaces:所以我有这些模型/接口:

export interface Contacts {
    email: string;
    phoneNumber: PhoneNumber;
    faxNumber: PhoneNumber;
}

export interface PhoneNumber {
    countryCode: string;
    predial: string;
    number: string;
}

And then in my Input component I have a form:然后在我的 Input 组件中,我有一个表单:

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+/)])
});

And in the html just the phone number for brevity:为简洁起见,在 html 中只是电话号码:

<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>

So I want two-way-data binding, that's why I am using the [(ngModel)] banana in the box , but how do I use two-way-data binding + mapping in the ngModel?所以我想要双向数据绑定,这就是为什么我[(ngModel)] banana in the box使用[(ngModel)] banana in the box ,但是如何[(ngModel)] banana in the box使用双向数据绑定 + 映射?

I cannot make a function that combines the country code and predial together and pass the value to the ngModel.我无法创建一个将国家代码和预拨号组合在一起并将值传递给 ngModel 的函数。

So how do I do this mapping in the UI?那么如何在 UI 中进行这种映射呢? What is a good practice?什么是好的做法?

You could split up the ngModel binding:您可以拆分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)"
>

And then set the correct fields on model change:然后在模型更改时设置正确的字段:

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?
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM