如何显式覆盖 AngularJS 模型去抖动?
How to explicitly override AngularJS model debouncing?
在我们 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 时,由于去抖动设置,新值尚未出现在模型中。
我能找到的解决方案的唯一提示 talks about using ngSubmit
instead of ngClick
,但我们既没有使用表单元素,也没有使用 ngClick
(后者至少不重要)。 Enter 按键通过 keydown
事件在自定义指令中捕获。
我能否以某种方式强制 AngularJS 跳过去抖动期并立即在该 keydown
事件的处理程序中根据我的命令更新模型?
请注意,一个明显的解决方法是在 keydown
处理程序中使用略高于去抖动延迟的 $timeout
,以确保模型已更新。不过,这对我来说真的很老套,而且也与用户期望在按下 Enter 键时立即做出反应的期望相冲突。
1:实际上,它是一个动态生成的UI,可以在嵌套容器中包含任意数量的此类文本输入。
最后,我放弃了基于 AngularJS 的 debounce
选项。
相反,我在输入模型更改时调用的任何地方使用了 _.debounce
from the lodash library。 _.debounce
提供了一个 flush()
方法,如果合适,该方法将强制立即调用去抖函数。因此,我现在在响应 Enter 键的击键时调用该方法。
我设法通过触发 'submit' 事件的自定义指令解决了这个问题:
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 + debounce 配置中配置事件:
<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()">
在我们 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 时,由于去抖动设置,新值尚未出现在模型中。
我能找到的解决方案的唯一提示 talks about using ngSubmit
instead of ngClick
,但我们既没有使用表单元素,也没有使用 ngClick
(后者至少不重要)。 Enter 按键通过 keydown
事件在自定义指令中捕获。
我能否以某种方式强制 AngularJS 跳过去抖动期并立即在该 keydown
事件的处理程序中根据我的命令更新模型?
请注意,一个明显的解决方法是在 keydown
处理程序中使用略高于去抖动延迟的 $timeout
,以确保模型已更新。不过,这对我来说真的很老套,而且也与用户期望在按下 Enter 键时立即做出反应的期望相冲突。
1:实际上,它是一个动态生成的UI,可以在嵌套容器中包含任意数量的此类文本输入。
最后,我放弃了基于 AngularJS 的 debounce
选项。
相反,我在输入模型更改时调用的任何地方使用了 _.debounce
from the lodash library。 _.debounce
提供了一个 flush()
方法,如果合适,该方法将强制立即调用去抖函数。因此,我现在在响应 Enter 键的击键时调用该方法。
我设法通过触发 'submit' 事件的自定义指令解决了这个问题:
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 + debounce 配置中配置事件:
<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()">