重置按钮擦除子组件输入的值
Reset button erases sub-component input's value
我分离了一个特殊的输入行,因为它经常被使用,所以最好创建一个新组件来单独处理它的所有内容。问题是,当我按下重置按钮时,位于新组件内的文本输入值不会更改回其原始值,它只是被删除了。我猜这是因为输入的值是动态连接到组件的输入参数的,而实际的输入字段没有 value="constant text"
属性。
页面的HTML:
<form>
<h3 class="form-group-caption"
>Mappaútvonalak
<input type="reset" class="ml-3 btn btn-light" value="Visszaállítás" />
</h3>
<app-stateful-text-input
label="FRM"
inputValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
组件的 HTML 包含一些包装器元素,并且:
<input
type="{{inputType}}"
class="form-control form-control-lg"
id="input-{{label}}"
value="{{inputValue}}"
(keypress)='onInputChanged($event)'
/>
对于一个输入,我可以编写一个 resetInputs()
方法,并在按下重置按钮时调用它。然而,这个新组件有很多实例,在多个页面中,在表单内的任何地方。如果我需要维护对所有它们的引用,只是为了能够调用该子组件中的方法,我就会失去将它们分开的关键点。
这种情况有什么简单的解决方法吗?
您可以在输入组件中设置默认值,并按照您的建议在父组件中将其与 resetInputs()
方法一起使用。
<app-stateful-text-input
label="FRM"
defaultValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
@Component({
selector: 'app-stateful-text-input',
template: `...`
})
export class StatefulTextInputComponent implements OnInit {
@Input()
public defaultValue: string;
public inputValue: string;
public ngOnInit(): void {
this.inputValue = this.defaultValue;
}
}
在您的父组件中,您可以迭代所有子自定义输入并在重置时设置旧值。
@Component({
selector: 'app-form-component',
template: `...`
})
class FormComponent {
@ViewChildren(StatefulTextInputComponent) statefulTextInputs: QueryList<StatefulTextInputComponent>;
...
public resetInputs(): void {
this.statefulTextInputs.forEach((item: StatefulTextInputComponent) => item.inputValue = item.defaultValue);
}
...
}
我可以通过向容器 <form>
添加一个 reset
事件侦听器来自动执行此操作,那时我用存储的属性覆盖 value
属性。
但是还是很丑,这需要额外的JS。我喜欢 "native solution" 重置按钮可以做它想做的事。
export class StatefulInputComponent implements OnInit {
@Input() inputValue: string;
@ViewChild('inputField', {static: true}) inputField: ElementRef;
defaultValue: string;
ngOnInit() {
this.defaultValue = this.inputValue;
let element = this.inputField.nativeElement as HTMLElement;
do {
element = element.parentElement;
} while (element != null && element.tagName !== 'FORM');
if (element == null) {
throw new Error('<app-stateful-input> must be placed inside a <form>!');
}
const form = element as HTMLFormElement;
form.addEventListener('reset', (event: Event) => {
const input = this.inputField.nativeElement as HTMLInputElement;
input.value = this.defaultValue;
event.preventDefault();
});
}
}
我分离了一个特殊的输入行,因为它经常被使用,所以最好创建一个新组件来单独处理它的所有内容。问题是,当我按下重置按钮时,位于新组件内的文本输入值不会更改回其原始值,它只是被删除了。我猜这是因为输入的值是动态连接到组件的输入参数的,而实际的输入字段没有 value="constant text"
属性。
页面的HTML:
<form>
<h3 class="form-group-caption"
>Mappaútvonalak
<input type="reset" class="ml-3 btn btn-light" value="Visszaállítás" />
</h3>
<app-stateful-text-input
label="FRM"
inputValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
组件的 HTML 包含一些包装器元素,并且:
<input
type="{{inputType}}"
class="form-control form-control-lg"
id="input-{{label}}"
value="{{inputValue}}"
(keypress)='onInputChanged($event)'
/>
对于一个输入,我可以编写一个 resetInputs()
方法,并在按下重置按钮时调用它。然而,这个新组件有很多实例,在多个页面中,在表单内的任何地方。如果我需要维护对所有它们的引用,只是为了能够调用该子组件中的方法,我就会失去将它们分开的关键点。
这种情况有什么简单的解决方法吗?
您可以在输入组件中设置默认值,并按照您的建议在父组件中将其与 resetInputs()
方法一起使用。
<app-stateful-text-input
label="FRM"
defaultValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
@Component({
selector: 'app-stateful-text-input',
template: `...`
})
export class StatefulTextInputComponent implements OnInit {
@Input()
public defaultValue: string;
public inputValue: string;
public ngOnInit(): void {
this.inputValue = this.defaultValue;
}
}
在您的父组件中,您可以迭代所有子自定义输入并在重置时设置旧值。
@Component({
selector: 'app-form-component',
template: `...`
})
class FormComponent {
@ViewChildren(StatefulTextInputComponent) statefulTextInputs: QueryList<StatefulTextInputComponent>;
...
public resetInputs(): void {
this.statefulTextInputs.forEach((item: StatefulTextInputComponent) => item.inputValue = item.defaultValue);
}
...
}
我可以通过向容器 <form>
添加一个 reset
事件侦听器来自动执行此操作,那时我用存储的属性覆盖 value
属性。
但是还是很丑,这需要额外的JS。我喜欢 "native solution" 重置按钮可以做它想做的事。
export class StatefulInputComponent implements OnInit {
@Input() inputValue: string;
@ViewChild('inputField', {static: true}) inputField: ElementRef;
defaultValue: string;
ngOnInit() {
this.defaultValue = this.inputValue;
let element = this.inputField.nativeElement as HTMLElement;
do {
element = element.parentElement;
} while (element != null && element.tagName !== 'FORM');
if (element == null) {
throw new Error('<app-stateful-input> must be placed inside a <form>!');
}
const form = element as HTMLFormElement;
form.addEventListener('reset', (event: Event) => {
const input = this.inputField.nativeElement as HTMLInputElement;
input.value = this.defaultValue;
event.preventDefault();
});
}
}