您好,我遇到了一个非常奇怪的问题,表单组值更改为单个更改订阅了两次。 以下是一些代码片段,描述了我正在尝试做的事情。不幸的是,由于某些连接,目前无法创建 stackblitz。 仅数字输入组件 html 文件
<mat-form-field appearance="outline" class="bsl-form-field-input">
<mat-label>{{ matLabel }}</mat-label>
<input
type="number"
matInput
[placeholder]="placeHolder"
[formControl]="formControl"
autocomplete="off"
appNumbersOnly
/>
</mat-form-field>
仅数字输入组件 ts 文件
import { Component, Input, OnDestroy, OnInit, forwardRef } from '@angular/core';
import {
FormControl,
NG_VALUE_ACCESSOR,
NumberValueAccessor,
} from '@angular/forms';
import { Subject } from 'rxjs';
@Component({
selector: 'app-numbers-only-input',
templateUrl: './numbers-only-input.component.html',
styleUrls: ['./numbers-only-input.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumbersOnlyInputComponent),
multi: true,
},
],
})
export class NumbersOnlyInputComponent
extends NumberValueAccessor
implements OnDestroy, OnInit
{
@Input()
formControl: FormControl;
@Input()
matLabel: string;
@Input()
placeHolder: string;
destroySubject = new Subject<void>();
ngOnDestroy(): void {
this.destroySubject.next();
this.destroySubject.complete();
}
ngOnInit(): void {
this.formControl.valueChanges.subscribe(value=>console.log(value))
}
}
仅数字指令文件,仅防止输入除数字之外的任何字符,并仅允许粘贴有效数字的值。
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appNumbersOnly]',
})
export class NumbersOnlyDirective {
regEx = '^[0-9]+$';
// only numbers are allowed
@HostListener('keypress', ['$event'])
onKeyPress(event: KeyboardEvent) {
return new RegExp(this.regEx).test(event.key);
}
// block paste for non numeric values
@HostListener('paste', ['$event'])
onPaste(event: ClipboardEvent) {
const pastedString = event?.clipboardData?.getData('text/plain');
if (pastedString && !Number.isNaN(+pastedString)) {
return true;
} else {
return false;
}
}
}
您可以使用rxjs来减少调用次数。通过获取唯一值并通过
throttleTime
排除多重排放。请在下面找到一个工作示例!
如果这不起作用,请在下面的 stackblitz 中复制问题并分享回来!
ngOnInit(): void {
this.formControl.valueChanges
.pipe(
distinctUntilChanged(),
throttleTime(500),
takeUntil(this.destroySubject)
)
.subscribe((value) => console.log(value));
}