在我们的 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()">