首页 文章

Angular 4反应形式 - FormArray在FormArray中无法获取路径

提问于
浏览
2

几天以来,我一直在尝试创建一个表单,该表单将允许用户创建产品,同时产品的变体可能与母产品具有不同的价格 . 例如,大小部件是10英镑,小小部件是5英镑 . 每次我最终得到的是FormArray中的FormArray,换句话说,我有一个包含各种变体的产品,这些变体有价格,但也有一系列属性 . 问题出现在我尝试添加控件时,我可以得到变化价格以便显示正常,但我无法获取路径以添加各种各样的各种变量控制,我只是得到一个关于ng的错误只有工作数组不是[对象,对象]或控件是空的...我有比我记忆中更多的错误!无论如何我的代码已被重写,并且可能比它开始时更糟糕!

首先是我的oninit中的表单:

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);
}

我添加变体的部分,有效,它仍然有我曾经尝试过的代码,并将添加到主要产品中的属性复制到变体中,我觉得它很有用,但却无法访问为了显示它们,variations.attributes不适用于路径 .

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());

}

为变体添加属性的部分,它不起作用,是我在component.ts中遇到问题的地方

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

最后,我的HTML更是一团糟lol:

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

  • 3

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

    例如

    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 ,它可以帮助你认识到你做错了什么

相关问题