编辑页面上的Angular 2,未在反应式表单数组中设置值

时间:2017-12-06 07:15:46

标签: angular angular2-forms angular-reactive-forms

这是我的product-edit-component.ts代码。在这里我添加了一个产品及其尺寸。大小将是多个。产品是创建的。但是当我编辑产品时,我希望所有的值都将被设置为JSON的对应值

export class ProductEditComponent implements OnInit {
    id: number;
    routeId: any;
    returnUrl: string;
    errorMessage: any;
    constructor(
      private http: Http,
      private router: Router,
      private route: ActivatedRoute,
      private productService
      : ProductService,
      private flashMessageService: FlashMessagesService,
      private fb: FormBuilder,

    ) { }


    @Input() product: FormGroup;

    ngOnInit() {
      this.routeId = this.route.params.subscribe(
        params => {
          this.id = +params['id'];
        }
      )
      let postRequest = this.route.params.flatMap((params: Params) =>
      this.productService.getProduct(+params['id']))
      postRequest.subscribe(response =>
        this.product.setValue({
          title: response.json().title,
          description: response.json().description,
          sizes_attributes: response.json().sizes_attributes[0]
        })
      );

      this.returnUrl = this.route.snapshot.queryParams['successUrl'] || '/products'
      this.product = this.fb.group({
        title: ['', [Validators.required, Validators.minLength(5)]],
        description: ['', [Validators.required, Validators.minLength(5)]],
        sizes_attributes: this.fb.array([
          this.fb.group({
            size_number: ['', [Validators.required,Validators.maxLength(5)]],
          })
        ])
      })
    }
  

此功能用于从模板添加大小:

    initSize() {
      return this.fb.group({
        size_number: ['', [Validators.required,Validators.maxLength(5)]],
      });
    }

    addSize() {
      const control = <FormArray>this.product.controls['sizes_attributes'];
      control.push(this.initSize());
    }
  

此功能用于从模板中删除大小:

    removeSize(i: number) {
      const control = <FormArray>this.product.controls['sizes_attributes'];
      control.removeAt(i);
    }
  }
  

这是编辑页面的模板:

<div class="container">
  <div class="row">
    <div class="col-sm-10">
      <div class="margin-20">
        <h4>Add Product</h4>
      </div>

      <form [formGroup]="product" novalidate (ngSubmit)="update(product)">
        <div class="form-group">
          <label>Title</label>
          <input type="text" class="form-control" formControlName="title">
          <small *ngIf="!product.controls.title.valid" class="text-danger">
            Name is required (minimum 5 characters).
          </small>
        </div>

        <div class="form-group">
          <label>Description</label>
          <input type="text" class="form-control" formControlName="description">
          <small *ngIf="!product.controls.description.valid" class="text-danger">
            Description is required (minimum 5 characters).
          </small>
        </div>

        <div formArrayName="sizes_attributes">
          <div *ngFor="let size of product.controls.sizes_attributes.controls; let i=index" class="panel panel-default">
            <div class="panel-heading">
              <span>Size {{i + 1}}</span>
              <span class="glyphicon glyphicon-remove pull-right" *ngIf="product.controls.sizes_attributes.controls.length > 1" (click)="removeSize(i)">X</span>
            </div>
            <div class="row" [formGroupName]="i">
              <div class="form-group col-md-6">
                <label>Size</label>
                <input type="text" class="form-control" formControlName="size_number">
                <small [hidden]="product.controls.sizes_attributes.controls[i].controls.size_number.valid" class="text-danger">
                  Size is required
                </small>
              </div>
            </div>
          </div>
        </div>

        <div class="margin-20">
          <a (click)="addSize()" style="cursor: default">
            Add another size +
          </a>
        </div>
        <div class="margin-20">
          <button type="submit" class="btn btn-primary pull-right" [disabled]="!product.valid">Submit</button>
        </div>
        <div class="clearfix"></div>

      </form>
    </div>
  </div>
</div>
  

来自API的Json数据:

{
    "code": 200,
    "id": 30,
    "title": "43434",
    "description": "343434",
    "created_at": "2017-12-05T10:19:39.316Z",
    "updated_at": "2017-12-05T10:19:39.316Z",
    "user_id": 4,
    "sizes_attributes": [
        {
            "id": 58,
            "size_number": "34",
            "product_id": 30,
            "created_at": "2017-12-05T10:19:39.317Z",
            "updated_at": "2017-12-05T10:19:39.317Z"
        },
        {
            "id": 60,
            "size_number": "77",
            "product_id": 30,
            "created_at": "2017-12-06T04:59:25.318Z",
            "updated_at": "2017-12-06T04:59:25.318Z"
        }
    ]
}
  

问题:

     

在上面的代码标题和描述中设置为产品形式,但大小数据未设置为sizes属性控件表单数组。   请帮忙

1 个答案:

答案 0 :(得分:0)

  ngOnInit() {
    this.routeId = this.route.params.subscribe(
      params => {
        this.id = +params['id'];
      }
    )
    let postRequest = this.route.params.flatMap((params: Params) =>
    this.productService.getProduct(+params['id']))
    postRequest.subscribe(response =>
      this.product.setValue({
        title: response.json().title,
        description: response.json().description,
        sizes_attributes: this.get_sizes(response.json().sizes_attributes),
      })
    );

    this.returnUrl = this.route.snapshot.queryParams['successUrl'] || '/products'
    this.product = this.fb.group({
      title: ['', [Validators.required, Validators.minLength(5)]],
      description: ['', [Validators.required, Validators.minLength(5)]],
      sizes_attributes: this.fb.array([

      ])
    })
  }
  

获取从现有数据库添加大小值的大小方法

  get_sizes(sizes){
     const control = <FormArray>this.product.controls['sizes_attributes']
    sizes.forEach((size, i) => {

       control.push(this.fb.group({
         id: size.id,
         size_number: [size.size_number, [Validators.required,Validators.maxLength(5)]],
         _destroy: '',
       })
     )
      })
      return control
  }