代码之家  ›  专栏  ›  技术社区  ›  Mark Perry

角度4反应形式-FormArray内的FormArray无法获取路径

  •  2
  • Mark Perry  · 技术社区  · 8 年前

    几天来,我一直在尝试创建一个表单,允许用户创建一个产品,同时该产品的变体可能与母产品的价格不同。例如,大部件是10,小部件是5。每次我得到的结果都是一个FormArray中的一个FormArray,换句话说,我有一个带有一系列变体的产品,这些变体有价格,但也有一系列属性。当我尝试添加控件时,问题来了,我可以让变体价格很好地显示出来,但我无法获得添加变体的路径。属性控件,我只是得到了一个关于NGO的错误,因为它只处理数组而不是[Object,Object],或者控件为null。。。我犯的错误比我记得的还要多!无论如何,我的代码,已经重新编写了很多,可能比它开始时更糟糕!

    ngOnInit() {
        this.getAttributes(); // Get Attribute Categories      
        this.form = this.fb.group({
            name: [''],
            price: [''],
            description: [''],
            stockRef: [''],
            attributes: this.fb.array([{
                attributeCategoryId: [''],
                name: [''],
            }]),
            variations: this.fb.array([{
                vprice: this.vprice,
                vattributes: this.vattributes
            }]),
        });
    }
    

    用于添加和删除主产品属性的部分,效果良好:

    addAttribute(id: any, name: any) {
        if (!id.value || !name.value)
            return;
        this.attributes = <FormArray>this.form.get('attributes');
        var newAttribute = this.fb.group({
            attributeCategoryId: [id.value],
            name: [name.value],
        });
        this.newlist.push({ name: [name.value].toString(), attributeCategoryId: [id.value].toString() });
        this.attributes.push(newAttribute);
    
        id.value = '';
        name.value = '';
    }
    removeAttr(i: any) {
        this.attributes.removeAt(i);
        this.list2 = [];
        this.newlist.splice(i, 1);
    }
    

    我添加变体的部分很有效,它仍然有我用来尝试将添加到主产品的属性复制到变体中的代码,我认为这很有效,但无法访问值以显示它们,变体。属性不适用于路径。

    initVariation() {
        let v = this.fb.group({
            price: [''],
            vattributes: this.attributes //COPIES main attributes            
        });
        this.attributes.reset(); //Reset the main attributes as they now      
        return v;                //belong to a variation 
    }
    addNewVar() {
        const control = <FormArray>this.form.controls['variations'];
        control.push(this.initVariation());
    
    }
    

    向变体添加属性的部分不起作用,这就是我的组件中存在问题的地方。输电系统

    addAttrRow() {
        const control = <FormArray>this.form.controls['variations.vattributes']
        control.push(this.initVattr())
    }
    initVattr() {
        let va = this.fb.group({
            vattributeCategoryId: [''],
            vname: ['']
        })
        return va;
    }
    

    最后,我的html更是一团糟,哈哈:

    <h1>New Product</h1>
    <form [formGroup]="form" (ngSubmit)="save()">
        <div class="row">
            <div class="col-md-6 col-sm-12">
                <div class="form-group">
                    <label>Product Name</label>
                    <div *ngIf="!form.get('name').valid" class="alert alert-danger">
                        {{ form.get('name').getError('remote') }}
                    </div>
                    <input [(ngModel)]="name" type="text" formControlName="name" class="form-control">
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-6 col-sm-12">
                <div class="form-group">
                    <label>Price</label>
                    <div *ngIf="!form.get('price').valid" class="alert alert-danger">
                        {{ form.get('price').getError('remote') }}
                    </div>
                    <input [(ngModel)]="price" type="number" formControlName="price" class="form-control">
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-6 col-sm-12">
                <div class="form-group">
                    <label>Product Description</label>
                    <div *ngIf="!form.get('description').valid" class="alert alert-danger">
                        {{ form.get('description').getError('remote') }}
                    </div>
                    <textarea formControlName="description" class="form-control"></textarea>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-6 col-sm-12">
                <div>
                    <h4>Attributes</h4>
                    <div class="form-inline" >
                        <div class="form-group">
                            <div formArrayName="attributes">
                                <select #ac name="attributeCategoryId">
                                    <option value="" selected>Category</option>
                                    <option *ngFor="let a of attriblist;let i = index" value="{{a.id}}">{{a.name}}</option>
                                </select>
                                <input #a name="name" placeholder="Attribute name" />
                            </div>
                        </div>
                        <button type="button" class="btn btn-default" (click)="addAttribute(ac,a)">Add Attribute</button>
                    </div>
                    <br>
                    <table class="table-bordered table table-striped">
                        <thead>
                            <tr>
                                <th>Attr. Category</th>
                                <th>Attr.</th>
                                <th><button type="button" (click)="addNewVar()" class="btn btn-primary">Add Variation</button></th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr *ngFor="let a of form.value.attributes; let i = index;"  >
                                <td *ngIf="i > 0">{{a.attributeCategoryId}}</td>
                                <td *ngIf="i > 0">{{a.name}}</td>
                                <td *ngIf="i > 0"><button (click)="removeAttr(i)" class="btn btn-danger">X</button></td>
                            </tr>
                        </tbody>
                    </table>
    
                </div>
            </div>
        </div>
        <!--Variations Start-->
        <div class="row" formArrayName="variations">
            <div *ngFor="let variation of form.controls.variations.controls; let i=index" [formGroupName]="i">
                <h5>Variation #{{ i + 1 }}</h5>
                <p></p>
                <div class="form-group">
                    <label>Variation Price</label>
                    <input name="vprice" style="max-width:50px" class="form-control">
                </div>
                <table>
                    <thead>
                        <tr>
                            <th>Attr. Category</th>
                            <th>Attr.</th>
                            <th><button class="btn btn-success" (click)="addAttrRow()">+</button></th>
                        </tr>
                    </thead>
                    <tbody name="vattributes">
                        <tr *ngFor="let attribute of variation.get('vattributes'); let ii = index;">
                            <td><input type="text" name="vattributeCateforyId" /></td>
                            <td><input type="text" name="vname" /></td>
                            <td><button (click)="removeVAttr(ii)" class="btn btn-danger">X</button></td>
                        </tr>
                    </tbody>
                </table>
                <button class="btn btn-danger" (click)="removeVariation(i)">Delete</button>
    
            </div>
            </div>
        <!--Variations End-->
        <br>
        <p>
            <button type="submit" class="btn btn-primary">Save</button>
        </p>
    </form>
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   yurzui    8 年前

    我看到你的代码中有很多错误。

    1) 您应该知道,在处理从中获取控制时,我们不需要忘记索引 FormArray

    const control = <FormArray>this.form.controls['variations.vattributes'];
    

    我们应该使用

    addAttrRow(index) {
      const control = <FormArray>this.form.get(['variations', index, 'vattributes']);
    

    2) 如果未指定类型 button submit 作为默认值。

    <button class="btn btn-success" (click)="addAttrRow()">+</button>
    

    因此,请尝试指定 type="button"

    3) 在对象上迭代

    *ngFor="let attribute of variation.get('vattributes');
    

    而您需要迭代数组

    *ngFor="let variation of form.controls.variations.controls;
    

    我创建了 Plunker Example

    推荐文章