重置按钮擦除子组件输入的值

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();
        });
    }
}