将文本输入绑定到可观察对象中的属性-Angular 2+ [英] Binding a text input to a property in an observable object - Angular 2+

查看:50
本文介绍了将文本输入绑定到可观察对象中的属性-Angular 2+的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 5构建应用程序,并且正在尝试构建动态表单.这种形式就像一个赌注或购物车,是一系列来自可观察服务的对象.我很难弄清楚如何添加输入字段并将其绑定到每个投注对象中的属性.

I am building an app Using Angular 5 and I am trying to build a dynamic form. This form, which is like a bet slip or shopping cart, is a array of objects which comes from a service as an observable. I am having difficulty figuring out how to add an input field and bind it to a property in each bet object.

可观察的 betSlipItems 数组如下所示:

The observable betSlipItems array looks like this:

[
  {
    "Id": 1,
    "betslipTeamName": "La Rochelle",
    "stake": null
  },
  {
    "Id": 2,
    "betslipTeamName": "North Queensland Cowboys",
    "stake": null
  }
] 

我想做的是创建一个输入字段并将其绑定到每个投注对象的' stake '属性.

And what I want to do is create an input field and bind it to the 'stake' property of each bet object.

到目前为止,这是我用于 bet-slip.component.ts 的代码:

This is my code for bet-slip.component.ts so far:

import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { Component, OnInit, Input } from '@angular/core';
import { Bets } from '../../../shared/models';
import { BetService } from '../../../shared/services/bet.service';
import { Observable } from 'rxjs';
import { of } from 'rxjs/observable/of';

@Component({
  selector: 'bet-slip',
  templateUrl: './bet-slip.component.html',
  styleUrls: ['./bet-slip.component.scss']
})

export class BetSlipComponent implements OnInit {

  public betSlipItems$: Observable<Bets[]> = of([]);
  public betSlipItems: Bets[] = [];
  public betsForm: FormGroup;

  constructor( private betService: BetService, private _fb: FormBuilder) {
    this.betSlipItems$ = this.betService.getBets();
  }

  ngOnInit() {

    this.betsForm = new FormGroup({
        stake: new FormControl()
    });

    this.betSlipItems$.subscribe((betSlipItems) => {
      this.betSlipItems = betSlipItems;
    });

  }
}

和我的组件 bet-slip.component.html 看起来像这样:

and my component bet-slip.component.html looks like this:

 <form [formGroup]="betsForm">
      <div *ngFor="let bet of betSlipItems; let i=index">
        {{bet.betslipTeamName }}
        <input type="text" formControlName="stake">
      </div>
 </form>

我知道这是不正确的.我该如何解决?

I know this is incorrect. How can I fix this?

推荐答案

问题是您必须知道什么需要和期望什么.我想您想制作一个不仅带有"Id","betslipTeamName"和"stake"(至少需要Id和股份)的表单数组.使用带有数组的ReactiveForm很容易.通常,我们有一个返回数据的服务.我举了一个完整的例子,希望对您有帮助

The problem is that you must know what need and what expect. I suppose you want to make a form Array with "Id","betslipTeamName" and "stake" (as minimum you need Id and stake) not only stake. To work with a ReactiveForm with an array it's easy. In general we have a service that return our data. I put a full example, I expect this help you

//simple service that read a json (you have one yet -it's only to complete my example-)
@Injectable()
export class AppDataService {

  constructor(private httpClient:HttpClient) { }
  read(key:any)
  {
    return this.httpClient.get('../assets/data.json')
  }
}

我们的组件具有这样的.html

Our component have a .html like this

<div *ngIf="yet">
<!--I put a *ngIf to avoid an error at first-->
  <form [formGroup]="dataForm" (ngSubmit)="submit(dataForm)" novalidate>
    <!--see that the "formArrayName" is "lista" 
    don't confuse with the *ngFor of "lista" (the lista in ngFor is a getter)
    -->
    <div formArrayName="lista" *ngFor="let lista of lista.controls;let i=index">
      <div [formGroupName]="i"> <!--it's necesary a formGroupName=i-->
      <!--we can use labels here -->
      {{labels[i].Id}}{{labels[i].Text}}
          <!--the input we need , some can be readOnly -->

          <input type="text" class="form-control" formControlName="Id">
          <input type="text" class="form-control" formControlName="betslipTeamName">
          <input type="text" class="form-control" formControlName="stake">
      </div>
      <hr>
    </div>
  </form>
   <!---this it's only to check the value of the form-->
  {{dataForm?.value |json}}
</div>

类似于组件

@Component({
  selector: 'app-app-form',
  templateUrl: './app-form.component.html',
  styleUrls: ['./app-form.component.css']
})
export class AppFormComponent implements OnInit {

  dataForm: null | undefined | FormGroup;  //we have a dataForm
  data: any;  //normally we have a data too. It's not necesary that the data was identical to dataFrom 
  labels:any[] //we create an array [{Id,Text}]
  yet:boolean=false;  //I use this variable when all it's ready

  get lista() {  //<--This is the gettet that we use in the *ngFor
    return (this.dataForm) ? this.dataForm.get('lista') : null;
  };

  constructor(private fb: FormBuilder, private dataService: AppDataService) { }

  ngOnInit() {
    let key: any;
    this.dataService.read(key).subscribe(
      (response:any[]) => {
    if (response) {
      this.data = response; //this.data is an array[{"Id": 1,..}.{"Id":2..}]
      //You can create a label array with Id,Text
      this.labels=response.map((item:any)=>{return {Id:item.Id,Text:item.betslipTeamName}})
      this.dataForm = this.createFormGroup(this.data);// dataForms is an object {lista:[{..},{..}]}
      this.yet=true;
    }
  });
  }
  submit(dataForm:any)
  {
    if (dataForm.valid)
    {
      console.log(dataForm.value);
    }
  }
  createFormGroup(data: any) {
    let lista = this.buildArray(data);  //create an array of Controls

    let dataForm = this.fb.group({
      lista: lista
    });
    //see that dataForms is an object {lista:[{..},{..}]}
    return dataForm;
  }

  buildArray(myArray: any[]) {
    //witch each data, we create a fbGroup 
    const arr = myArray.map(data => {
      return this.fb.group({
        "Id": [data.Id], //we can omit some control
        "betslipTeamName": [data.betslipTeamName],
        "stake": [data.stake],
      });
    });
    //And return a array of fbGroup
    return this.fb.array(arr);
  }
}

这篇关于将文本输入绑定到可观察对象中的属性-Angular 2+的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆