如何显式覆盖 AngularJS 模型去抖?



在我们的 AngularJS 1.* 应用程序的一个页面上,我正在查看一个文本输入1,其debounce设置为大于零的值。它的配置大致如下:

<input type="text" data-ng-model="data.value1"
ng-model-options="{ updateOn: 'default blur', debounce: { default: 2500, blur: 0 }}"
data-ng-change="onValueChanged()">

通过该文本输入输入的数据在单击按钮或按Enter键时进行处理。

现在,问题是当用户在更改值后立即按Enter时,由于去抖动设置,新值尚未在模型中。

我能找到的解决方案的唯一提示是使用ngSubmit而不是ngClick,但我们既没有使用表单元素也没有使用ngClick(后者至少在重要的地方不重要)。Enter按键通过keydown事件在自定义指令中捕获。

我可以以某种方式强制 AngularJS 跳过去抖动期并立即在该keydown事件的处理程序中更新我的命令上的模型吗?

请注意,一个明显的解决方法是在keydown处理程序中使用略高于去抖延迟的$timeout,以确保模型已更新。不过,这对我来说真的很笨拙,并且也与用户在按Enter键时立即做出反应的期望相冲突。


1:实际上,它是一个动态生成的 UI,可能包含嵌套容器中任意数量的此类文本输入。

最后,我放弃了基于 AngularJS 的debounce选项。

相反,我在任何地方使用了 lodash 库中的_.debounce,这些在更改我的输入模型时被调用。_.debounce提供了一种flush()方法,该方法将在适当的情况下强制立即调用去抖函数。因此,我现在在对Enter键的击键做出反应时调用该方法。

我设法通过触发"提交"事件的自定义指令解决了这个问题:

angular.module('...')
.directive('submitListener', () =>
({
restrict: 'A',
require: 'ngModel',
link(scope, elem, attrs, ngModelCtrl) {
elem.on('keyup', ($event) => {
if ($event.keyCode === 13) {
console.log(`submitted !`)
ngModelCtrl.$setViewValue(elem.val(), 'submit')
}
})
},
})
)

并在输入上使用指令并在 ng-model-options + 去抖动配置中配置事件:

<input type="text" data-ng-model="data.value1"
ng-model-options="{ updateOn: 'default blur submit', debounce: { default: 2500, blur: 0, submit: 0 }}"
submit-listener
data-ng-change="onValueChanged()">

最新更新