【问题标题】:Angular - Building form based on user inputAngular - 基于用户输入的构建表单
【发布时间】:2018-11-22 18:08:22
【问题描述】:

我正在构建一个应该是动态的网络表单。
当用户从列表中选择一个选项时,会根据他的输入生成下一个表单输入。
例如:

<mat-form-field>
     <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="TypeChosen(row.Type, row)">
         <mat-option [value]="0">Treatment</mat-option>
         <mat-option [value]="1">Travel</mat-option>
         <mat-option [value]="2">Medication</mat-option>
         <mat-option [value]="3">Equipment</mat-option>
     </mat-select>
</mat-form-field>

如果他选择“治疗”类型,他会得到另一个选择输入,其中包含一些选项和一些其他输入,如果他选择不同的类型,他会得到不同的选项和其他输入。

我了解我需要动态生成 HTML 内容,并且可能需要动态组件。
以简单的方式做到这一点的最佳方法是什么?

【问题讨论】:

  • 动态组件可以...因为 Angular 不允许从您的 ts 文件中放入动态 html(您可以使用 domsanatizer 做到这一点)
  • 你为什么不使用*ngIf指令?这就是 html 在 Angular 中的工作方式,还有一些其他指令,它们的语法中也包含 *
  • @PranayRana 因为我没有经验,所以一个例子会对我有所帮助。谢谢。
  • @Korte 有太多的选项和条件流程,*ngIf 使代码复杂化并使其混乱。
  • 我仍然建议将 *ngIf 与包含条件的短函数结合使用。像 *ngIf="shouldIshowX()" 和 shouldIshowX() { return condition1 && condition2 && !condition3 }

标签: html angular dom angular-forms


【解决方案1】:

要动态添加选项,角度提供 (*ngFor)。

<mat-form-field>
     <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="TypeChosen(row.Type, row)" *ngFor="let option of options; let i = index">
         <mat-option (click)="updateOptions(option)" [value]="{{i}}">option.text</mat-option>
     </mat-select>
</mat-form-field> 

在你的控制器.ts中

private options = [];

private initOptions(){
this.options = [
{text:'Treatment' , possibleOptionsRelates:[text:'possible1']},
{text:'Travel' , possibleOptionsRelates:[text:'possible12']},
{text:'Medication' , possibleOptionsRelates:[text:'possible13']}];
}
private updateOptions(option){
     this.options.push(...option.possibleOptionsRelates);
}

【讨论】:

  • 谢谢。这是一个好的开始,但比这更复杂,因为我不是只添加一个带有选项的mat-select,而是添加一些其他输入,其中一些用于治疗,一些用于旅行等。
  • 其他 mat-select 是否共享相同的选项??
  • 没有。每个都有自己的条件和选项。
【解决方案2】:

我建议为每个子表单创建一个组件,然后根据所选选项*ngIf 它们,如下所示:

<!-- component.html -->

<mat-form-field>
  <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="onTypeChosen(row.Type, row)">
    <mat-option [value]="0">Treatment</mat-option>
    <mat-option [value]="1">Travel</mat-option>
    <mat-option [value]="2">Medication</mat-option>
    <mat-option [value]="3">Equipment</mat-option>
  </mat-select>
</mat-form-field>

<my-treatment-component *ngIf="type === 0" [someInput]="'some value'"></my-treatment-component>
<my-travel-component *ngIf="type === 1" [somethingElse]="true"></my-travel-component>
<my-medication-component *ngIf="type === 2" (someOutput)="onMedicationOutput($event)"></my-medication-component>
<my-equipment-component *ngIf="type === 3"></my-equipment-component>

如果你已经有一些东西保存了你的类型选择,你可以将它绑定到*ngIfs。如果没有,请在控制器类中创建一个字段并将所选类型保存在其中。

// component.ts

public type: number | null = null;

public onTypeChosen(type: number, row): void {
  this.type = type;
}

如果您的子表单具有可重用的部分(或基本相同,无配置),通常将可重用的代码提取到它们自身的组件中并将它们组合在一起是一种很好的做法。

希望这会有所帮助:-)

【讨论】:

    猜你喜欢
    • 2013-08-02
    • 1970-01-01
    • 2012-05-25
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2014-11-21
    • 2012-01-13
    相关资源
    最近更新 更多