Angular 4 动态表单 : Dependent Dropdown

标签 angular forms typescript dynamic angular-forms

我正在创建一个基于 Angular 4 Dynamic Forms 的动态表单.

一切顺利!但是,我遇到了下拉列表的问题。我想要一个依赖下拉列表。当用户在下拉列表中选择一个值时,它将显示基于属性的复选框 - 可能是 name

服务

  new DropdownInput({
    key: 'dropdown',
    label: 'Dropdown Testing',
    options: [
      {key: 'example1',  value: 'Example 1'},
      {key: 'example2',  value: 'Example 2'}
    ],
    order: 1
  }),

  new CheckboxInput({
    key: 'checkbox1',
    label: 'checkbox1 - example1',
    name: 'example1',
    order: 2
  }),

  new CheckboxInput({
    key: 'checkbox2',
    label: 'checkbox2 - example1',
    name: 'example1',
    order: 3
  }),

  new CheckboxInput({
    key: 'checkbox3',
    label: 'checkbox3 - example2',
    name: 'example2',
    order: 4
  }),

  new CheckboxInput({
    key: 'checkbox4',
    label: 'checkbox4 - example2',
    name: 'example2',
    order: 5
  })

html

<!-- CHECKBOX -->

<div class="col-xs-12" *ngSwitchCase="'checkbox'">

  <input class="form-check-input"
         type="checkbox"
         [formControlName]="input.key"
         [id]="input.key"
         [name]="input.name">

  <label class="control-label"
         [attr.for]="input.key">{{input.label}}</label>
  <a class="info-tooltip"><i class="fa fa-question-circle" aria-hidden="true"></i></a>

  <span class="help-block"
        *ngIf="!isValid">{{inputError}}</span>

</div>

<!-- DROPDOWN -->

<div class="col-xs-12" *ngSwitchCase="'dropdown'">

  <label class="control-label"
         [attr.for]="input.key">{{input.label}}</label>
  <a class="info-tooltip"><i class="fa fa-question-circle" aria-hidden="true"></i></a>

  <span class="help-block"
        *ngIf="!isValid">{{inputError}}</span>

  <select [id]="input.key"
          [formControlName]="input.key">
    <option *ngFor="let opt of input.options"
            [value]="opt.key">{{opt.value}}</option>
  </select>

</div>

所以在此示例中,如果用户单击示例 1 - 我只想显示复选框 1 和 2。这可能吗?我应该以不同的方式格式化数据吗?

注意 1:我找到了有关如何从依赖下拉列表转到另一个下拉列表 (Angular 2 Dynamic Forms: How to create dependent dropdown ) 的链接,但不知道如何有效地将其与复选框一起使用。

注意 2:我将复选框与文本框(未显示)分开的原因是它们在应用程序中的视觉显示方式。我知道我可以将它们结合起来以获得更少/更高效的代码。

最佳答案

我会在基本模型中添加一个名为 showWhen 的选项:

base.model.ts

export class BaseModel<T> {
  value: T;
  key: string;
  label: string;
  required: boolean;
  order: number;
  controlType: string;
  showWhen: ControlCondition; <===================== new option

  constructor(options: {
    value?: T,
    key?: string,
    label?: string,
    required?: boolean,
    order?: number,
    controlType?: string,
    showWhen?: ControlCondition
  } = {}) {
    this.value = options.value;
    this.key = options.key || '';
    this.label = options.label || '';
    this.required = !!options.required;
    this.showWhen = options.showWhen;
    this.order = options.order === undefined ? 1 : options.order;
    this.controlType = options.controlType || '';
  }
}

export class ControlCondition {
  key: string;
  value: string;
}

如您所见,它需要 keyvalue。根据这些值,我们可以决定是否显示控制。

现在您可以描述显示控件的条件,例如:

new DropdownInput({
  key: 'dropdown',
  label: 'Dropdown Testing',
  options: [
    { key: 'example1', value: 'Example 1' },
    { key: 'example2', value: 'Example 2' }
  ],
  order: 1
}),

new CheckboxInput({
  key: 'checkbox1',
  label: 'checkbox1 - example1',
  showWhen: {
    key: 'dropdown',   // if control with key `dropdown` has value `example 1` then show
    value: 'example1',
  },
  order: 2
}),

现在转到 Angular 教程中名为 DynamicFormQuestionComponent 的组件。在我的示例中,我将其称为 DynamicFormComponent。这里我们需要添加显示/隐藏控件的逻辑:

动态表单.component.ts

export class DynamicFormComponent implements OnInit, OnDestroy {
  @Input() input: BaseModel<any>;
  @Input() form: FormGroup;

  control: FormControl;

  hidden: boolean;

  subscription: Subscription;

  ngOnInit() {
    this.control = this.form.get(this.input.key) as FormControl;
    this.setUpConditions();
  }

  setUpConditions() {
    if (!this.input.showWhen) {
      return;
    }

    let relatedControl = this.form.get(this.input.showWhen.key);
    if (!relatedControl) {
      return;
    }

    this.updateHidden();
    this.subscription = relatedControl.valueChanges.subscribe(x => this.updateHidden());
  }

  updateHidden(): void {
    let relatedControl = this.form.get(this.input.showWhen.key);
    this.hidden = relatedControl.value !== this.input.showWhen.value;

    this.hidden ? this.control.disable() : this.control.enable();
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

你需要做的最后一件事是在模板中添加*ngIf="!hidden"

Ng-run Example

关于Angular 4 动态表单 : Dependent Dropdown,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48289418/

相关文章:

Typescript 1.5,导入 ES6 模块

javascript - *ngFor angular 2 when creating tabs - 表达式在检查后发生了变化

typescript - 将特定目录中的 *.ts 文件编译为单个文件

angular - 模块 'MatSpinner' 导入了意外指令 'AppModule'。请添加@NgModule 注解

css - 创建没有单选按钮和自定义 CSS 样式的单选按钮组

javascript - 不同组件中的提交按钮会造成可访问性问题

具有多个文件扩展名和大写的 PHP 上传表单

javascript - 需要通过浏览器将 MQTT 与 Ably 结合使用的帮助

javascript - (Angular2) JSON数据(http.get())未定义,数据未在组件中更新

angular - 函数在第二次调用时被记录