【问题标题】:Angular 4 Dynamic Forms: Dependent DropdownAngular 4 动态表单:依赖下拉列表
【发布时间】:2018-06-25 15:27:20
【问题描述】:

我正在创建一个基于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:我的复选框与文本框(未显示)分开的原因是它们在应用程序中的可视化显示方式。我知道我可以将它们组合起来以获得更少/更高效的代码。

【问题讨论】:

    标签: angular forms typescript dynamic angular-forms


    【解决方案1】:

    我会在基本模型中添加一个名为 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。这里我们需要添加显示/隐藏控件的逻辑:

    dynamic-form.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

    【讨论】:

    • 谢谢!我有一个相当奇怪的要求。但是当我将数据发送到服务器时,我需要发送所有复选框中的数据。例如,假设用户点击了下拉列表中的示例 2,并且仅点击了复选框 3(未选中,然后未选中)。数据读取:dropdown: example2, checkbox3: true,但我希望数据读取:dropdown: example2, checkbox1: false, checkbox2: false, checkbox3: true, checkbox4: false。这可能吗?
    • 有一行this.hidden ? this.control.disable() : this.control.enable(); 对此负责。您还可以从 formGroup 中读取 getRawValue。我已经更新了示例
    • 如果this.hiddentrue,也可以调用reset方法值
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多