angular directive encapsulating a delay for ng-change

前端 未结 4 698
南笙
南笙 2020-11-28 09:21

I have a search input field with a requery function bound to the ng-change.

 
4条回答
  •  粉色の甜心
    2020-11-28 09:49

    I know i'm late to the game but,hopefully this will help anyone still using 1.2. Pre ng-model-options i found this worked for me, as ngchange will not fire when the value is invalid.

    this is a slight variation on @doug's answer as it uses ngKeypress which doesn't care what state the model is in.

    function delayChangeDirective($timeout) {
        var directive = {
            restrict: 'A',
            priority: 10,
            controller: delayChangeController,
            controllerAs: "$ctrl",
            scope: true,
            compile: function compileHandler(element, attributes) {
                var expression = attributes['ngKeypress'];
                if (!expression)
                    return;
    
                var ngModel = attributes['ngModel'];
                if (ngModel) {
                    attributes['ngModel'] = '$parent.' + ngModel;
                }
                attributes['ngKeypress'] = '$$delay.execute()';
    
                return {
                    post: postHandler,
                };
    
                function postHandler(scope, element, attributes) {
                    scope.$$delay = {
                        expression: expression,
                        delay: scope.$eval(attributes['ngKeypressDelay']),
                        execute: function () {
                            var state = scope.$$delay;
                            state.then = Date.now();
                            if (scope.promise) {
                                $timeout.cancel(scope.promise);
                            }
    
                            scope.promise = $timeout(function() {
                                delayedActionHandler(scope, state, expression);
                                scope.promise = null;
                            }, state.delay);
                        }
                    };
                }
            }
        };
    
        function delayedActionHandler(scope, state, expression) {
            var now = Date.now();
            if (now - state.then >= state.delay) {
                scope.$parent.$eval(expression);
            }
        };
    
        return directive;
    };
    

提交回复
热议问题