1

我的 HTML 中有一个输入字段,如下所示:

<input (keyup)="userInput($event)" type="text">

在我的组件中,我接受用户输入并与后端检查它是否是有效输入。在进行此调用之前,我对变量进行了简单的空检查。

userInput(e: any): void {
    this.userInputText = e.target.value;
    if (this.userInputText === '') { //Empty string check
        this.validInput = false;
    } else { // Check backend for availability
        this.userInput.next(this.userInputText);
    }
}

我的用户输入主题是

this.userInput
.debounceTime(1000)
.switchMap((val) => {
    return this.checkValidity(val); //service call
}).subscribe((res) => {
    this.validInput = res.status;
}, (err) => {
    ResponseHandler(err);
});

问题是我做的空支票。

想象一下用户输入两个字符“of”,我将其显示为有效(通过拨打电话)。

如果用户点击退格键(输入现在是“o”),请等待一秒钟(导致调用文本“o”)并按退格键删除“o”(导致用户输入为空)我的状态显示无效导致输入字段为空。

然后 ajax 调用响应返回(对于文本 'o',这是有效的)并且我显示有效。所以我最终显示对空字符串有效。我该如何解决这个问题?有任何想法吗?

4

2 回答 2

1

您只需要将空支票放入可观察的流中,而不需要周围的工作......

this.userInput
 .debounceTime(1000)
 .distinctUntilChanged()
 .switchMap((val) => (val) ? this.checkValidity(val) : Observable.of({status: false}))
 .subscribe((res) => {
       this.validInput = res.status;
 }, (err) => {
    ResponseHandler(err);
 });

只需将键直接绑定到用户输入主题

由于 switchmap 运算符的工作方式,这解决了您的时间问题。

switchMap 接受一个值并将其映射到一个新的内部 observable 的订阅中,但更重要的是,它取消并忽略来自先前订阅的内部 observable 的值。这就是为什么使用 switch map,如果用户输入 w 然后 o,则 switch map 收到“w”然后“wo”并不重要,因为一旦它获得第二个值,异步“w”查询是否有返回与否,或者如果(以某种方式)“wo”查询击败了“w”查询,因为它会在收到新的“wo”值后立即忽略或取消“w”查询,同样如此空白值,就好像用户在之前的查询完成之前删除了他们的输入,switchMap 将忽略或取消所有之前未完成的查询,并且它只会从最新的内部 observable 返回模拟的无效查询结果。这就是为什么它被称为 switchMap,它切换到并映射到最新的内部 observable。

如果您要使用像 mergeMap 这样的运算符,这是一个不同的高阶运算符,它也映射到一个新的内部 observable,这个过程将不起作用,因为 mergeMap 不会切换,它会按顺序返回内部 observable 的所有值他们到达,不管有什么新价值。有时这就是你所追求的,但在这种情况下不是。

额外提示,我添加的 distinctUntilChanged() 运算符使这个过程更有效率,就好像用户要执行类似输入 w 的操作,(执行查询)然后输入 o 并在去抖时间范围内立即删除 o,它会忽略发送的下一个“w”,因为它只将新值传递给 switchmap 并忽略顺序重复值,因此您不必重新查询“w”

于 2017-09-29T23:44:05.267 回答
0

问题是您正在执行异步操作并期望同步结果。您需要找到一种方法来解决程序的异步性质。

立即想到的一些可能的解决方案:

1) 您可以在进行服务器端验证时禁用输入。

2) 由于解决方案 1 不太流畅,您可以考虑在将请求发送到服务器之前设置一个标志(例如input_changed_during request = false;,在输入更改时修改其值(例如input_changed_during_request = true;,然后在收到来自如果在验证过程中修改了输入,则服务器并丢弃您的验证结果。

3)您可以在客户端进行去抖动输入验证,然后在提交时重新验证输入。

于 2017-09-29T23:43:13.847 回答