Angular 4 个动态表单:依赖下拉列表
Angular 4 Dynamic Forms: Dependent Dropdown
我正在创建一个基于 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:我发现 link 关于如何从依赖下拉列表转到另一个下拉列表(Angular 2 动态表单:如何创建依赖下拉列表
), 但不知道如何有效地使用复选框。
注意 2:我将复选框与文本框(未显示)分开的原因是它们在应用程序中的视觉显示方式。我知道我可以将它们组合起来以获得 less/more 高效代码。
我会在基本模型中添加一个名为 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;
}
如您所见,需要 key
和 value
。根据这些值,我们可以决定是否显示控制。
现在您可以描述显示控件的条件,例如:
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
。这里我们需要为showing/hidding控件添加逻辑:
动态-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"
我正在创建一个基于 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:我发现 link 关于如何从依赖下拉列表转到另一个下拉列表(Angular 2 动态表单:如何创建依赖下拉列表 ), 但不知道如何有效地使用复选框。
注意 2:我将复选框与文本框(未显示)分开的原因是它们在应用程序中的视觉显示方式。我知道我可以将它们组合起来以获得 less/more 高效代码。
我会在基本模型中添加一个名为 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;
}
如您所见,需要 key
和 value
。根据这些值,我们可以决定是否显示控制。
现在您可以描述显示控件的条件,例如:
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
。这里我们需要为showing/hidding控件添加逻辑:
动态-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"