【问题标题】:In Angular version 4 how can I use ngModel with Formarray select objects在 Angular 版本 4 中,如何将 ngModel 与 Formarray 选择对象一起使用
【发布时间】:2023-03-29 03:28:01
【问题描述】:

我已经成功设置了一个有两个控件的 Formarray。控件在 HTML 表单中设置为选择对象。我可以成功推送和显示多个元素集,但是当我尝试更改 Formarray 的第一个元素中选择对象的值时,其他 Formarray 元素选择对象采用相同的值。我正在使用 [(ngModel)] 将值绑定到对象,我相信这就是为什么值总是相同的。我尝试使用 Formarray 索引使用带有 [(ngModel)]=stringArray[i] 的数组变量,但在加载页面时出现错误。

谁能建议如何使用 [(ngModel)] 或其他机制获取选择对象的值?我正在使用 ng-lightning 选择组件(版本 1.3.0)和 SLDS Lightning Design CSS。我正在使用 Angular 4.1.3 版。在我的应用程序的其他部分,我需要使用带有字符串的 [(ngModel)] 来获取选择对象的值。选择值是一个对象数组,而不是像字符串这样的原始变量。该组件没有定义 onSelect() 函数。

HTML:

<form [formGroup]="callFlowForm">
  <div formArrayName="callDevices">
    <!-- Check the correct way to iterate your form array -->
    <div *ngFor="let callDevice of callFlowForm.controls.callDevices.controls; let i=index"  [formGroupName]="i">
      <div class="form-group">
        <div class="slds-form-element slds-size--8-of-8">
          <ngl-form-element label="Device #: {{ i + 1 }}" class="slds-m-top--small">
            <select nglFormControl class="slds-select"
                    formControlName="callAsset"
                    [(ngModel)]="selectedDevice"
                    ngDefaultControl >
                <option *ngFor="let device of devices"
                    [value]="device.id">{{device.assetName}}
                </option>
            </select>
          </ngl-form-element>
        </div>
      </div>
      <div class="form-group">
        <div class="slds-form-element slds-size--8-of-8">
          <ngl-form-element label="Protocol:" class="slds-m-top--small">
            <select nglFormControl class="slds-select"
                    formControlName="assetTransport"
                    [(ngModel)]="selectedTransport"
                    ngDefaultControl >
                <option *ngFor="let protocol of transports"
                    [value]="protocol.id">{{protocol.type}}
                </option>
            </select>
          </ngl-form-element>
        </div>
      </div>
      <button *ngIf="callFlowForm.controls.callDevices.controls.length > 1" (click)="deleteDevice(i)" class="btn btn-danger">Delete Button</button>
    </div>
  </div>
  <button type="button" (click)="addDevice()" class="btn btn-primary">Add Device</button>
</form>

组件:

selectedTransport: string;
selectedDevice: string;
public callFlowForm: FormGroup;

transports: SipTransport[] = [{'id': 1, 'type': 'UDP'},
                              {'id': 2, 'type': 'TCP'},
                              {'id': 3, 'type': 'TLS'}
                             ];
devices: Asset[] = [{'id': 1, 'assetName': 'VCS', 'type': 'SIP Registrar'},
                    {'id': 1, 'assetName': 'CUCM', 'type': 'Call Control'},
                    {'id': 1, 'assetName': 'SBC', 'type': 'Call Control'},
                    {'id': 1, 'assetName': 'EX60', 'type': 'Endpoint'}
                   ];

constructor(private dialService: DialService,
    private formBuilder: FormBuilder
) { }

ngOnInit() {
    this.selectedDevice = '1';
    this.selectedTransport = '1';
    this.callFlowForm = this.formBuilder.group({
      callDevices: this.formBuilder.array([this.addDevices()]) // here
    });

}

addDevices() {
      return this.formBuilder.group({
          callAsset: [''],
          assetTransport: ['']
      });
}

addDevice() { 
  const control = <FormArray>this.callFlowForm.controls['callDevices'];
  control.push(this.addDevices());
}

deleteDevice(index: number) {
  const control = <FormArray>this.callFlowForm.controls['callDevices'];
  control.removeAt(index);
}

【问题讨论】:

  • 您是绝对正确的,这是因为 ngModel。双向绑定在反应形式中高度不鼓励。我无法理解为什么您需要在这里进行双向绑定。为什么不改用formcontrol。这就是应该使用的:)
  • 嗨@AJT_82,我不需要 ngModel,但我已经在其他表单中使用过它,尤其是在我想用要编辑的当前值预先填充字段的编辑表单中。您的建议有效,因为我能够在不使用 ngModel 的情况下控制台记录选择的值。我只需要弄清楚提交时如何遍历组件中的formarray数据。我在控制台中得到了这个:这是我的表单 {"callDevices":[{"callAsset":"24","assetTransport":"2"},{"callAsset":"34","assetTransport":"1 "}]}
  • 您还可以使用表单控件设置预选值,方法是在设置值之前不构建表单。或者然后在您收到它们时通过带有值的修补表单......如果这是异步的。但是关于你的问题...... 我只需要弄清楚提交时如何迭代组件中的formarray数据为什么需要迭代它?我的意思是你想通过迭代来完成什么?作为旁注,这就像迭代任何数组:)

标签: angular select ng-lightning


【解决方案1】:

你为什么不这样做?

组件类:

selectedDevice: Asset;

HTML 代码:

           <select nglFormControl class="slds-select"
                formControlName="callAsset"
                [(ngModel)]="selectedDevice"
                ngDefaultControl >
            <option *ngFor="let device of devices"
                [value]="device">{{device.assetName}}
            </option>
        </select>`

【讨论】:

  • 您的建议无效。任何版本的 ngModel 似乎都只是将选择对象捆绑在一起。删除 ngModel 似乎是正确的选择,我现在只需要弄清楚如何遍历 formarray 值。谢谢。
【解决方案2】:

感谢@AJT_82 帮助我朝着正确的方向前进。这个问题的措辞可能不是最好的,因为答案是您不要在 formarray 中使用 ngModel。您需要通过表单控件设置和检索值。当 Internet 上的示例试图解释“模板驱动”与“模型驱动”或“反应式”表单之间的区别时,这让我感到困惑。它们似乎总是一样的。

HTML 应该是这样的。

HTML:

<select nglFormControl class="slds-select"
        formControlName="callAsset"
        ngDefaultControl >
        <option *ngFor="let device of devices"
           [value]="device.id">{{device.assetName}}
        </option>
</select>

在我的应用程序中,我使用数组值来搜索更大的集合。当我想获取表单的值时,我实现了这个:

组件:

const formValue1 = this.callFlowForm.value;

// this allows me to iterate through all devices in the formarray
// and push those values into a list for sorting and further processing
formValue1.callDevices.forEach((element: any) => {
    allDevices.push(element.callDevice);
});

不是在这个例子中,而是在另一个表单中,我需要设置表单控件的值。我使用了 form.setValue({}) ,您需要在其中设置所有表单控件的值。然后,如果您只需要编辑单个值,则使用 form.patchValue({})。其他形式的集合的一个例子就是这个。

设置值:

this.dialForm.setValue({
   id: this.editDialplan.id,
   number: this.editDialplan.number,
   domainid: this.editDialplan.domainid.id
});

patchValue:

this.dialForm.patchValue({
   number: this.editDialplan.number,
});

【讨论】:

    猜你喜欢
    • 2021-07-04
    • 2019-01-21
    • 2018-01-24
    • 2019-01-17
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 2018-05-06
    • 2019-06-06
    相关资源
    最近更新 更多