Как стать автором
Обновить

Комментарии 16

От переводчика: если вам понравилась статья, то лучшая благодарность — зеленая стрелочка в профиле. Спасибо :)

От читателя: клянчить карму некрасиво. Пожалуйста.
Ребята из прекрасной организации Rx, сделали расширение под Angular. Теперь возможности Rx(Reactive programming) есть и в Angular, при том, что мне очень понравилось, что можно использовать ng-click, а в коде обрабатывать и пропускать через фильтры, мапы, редьюсы.
Вот пример throttle github.com/Reactive-Extensions/rx.angular.js/blob/master/examples/%24toObservable/app.js
Строго говоря, Rx — не организация, а «reactive extensions». А вот организация, которая стоит за реализацией «реактивного» подохода на JavaScript — Microsoft. Кроме того, этот подход уже доступен во множестве других библиотек из js (jquery, angular, node.js и т.д. — github.com/Reactive-Extensions).

Плюс известная Netflix развивает RxJava, а на гитхабе RxJS можно найти порты для ruby, c#, php, python и т.д.
Я не стал дальше расписывать что это и как) Думаю для этого лучше сделать отдельную статью =) Мэтью радует новыми фичами.
По оптимизации я бы добавил вот ещё что: если приложение начинает разрастаться (сотни вотчеров), лучше автокомплит выделить в отдельный компонент (директиву) со своим скоупом и использовать $scope.$digest() (который обновит только скоуп компонента) вместо $scope.$apply(), который обновляет состояние всех скоупов, начиная с корня ($rootScope).
ИМХО, самый простой вариант написать свой «debounce» только с использование $timeout и не будет нужды вызывать $apply
$timeout это обычная обёртка над setTimeout (+Promise), коллбэк которого всё-равно вызывает $apply
Да и по этому вызывать $apply руками нужды не будет. Я именно об этом и говорил.
Когда делал поле для поиска, написал директиву, откладывающую срабатывание по вводу

app.directive('changeTimeout', function() {
        return {
            require: 'ngModel',
            link: function(scope, elem, attr, ctrl) {
                if (!attr.ngChange) {
                    throw new TypeError('ng-change directive not present');
                }

                angular.forEach(ctrl.$viewChangeListeners, function(listener, index) {
                    ctrl.$viewChangeListeners[index] = _.debounce(function() {
                        scope.$apply(attr.ngChange);
                    }, attr.changeTimeout || 0)
                });
            }
        }
    });
что делает свойство $viewChangeListeners?
Туда записываются колбэки из ng-change
только из ng-change или для других ивентов тоже?
Всё что вызывается при изменении видимых данных. ng-keyup и т. п. тоже относится
В своем проекте написали такой декоратор:

angular.module('ngDebounce', []).config ['$provide', ($provide) ->
    $provide.decorator '$timeout', ['$delegate', '$q', ($delegate, $q) ->
        $delegate.debounce = (func, wait, immediate) ->
            timeout = undefined
            deferred = $q.defer()
            (->
                context = this
                args = arguments
                later = ->
                    timeout = null
                    unless immediate
                        deferred.resolve func.apply(context, args)
                        deferred = $q.defer()

                callNow = immediate and not timeout
                $delegate.cancel timeout  if timeout
                timeout = $delegate(later, wait)
                if callNow
                    deferred.resolve func.apply(context, args)
                    deferred = $q.defer()
                deferred.promise)
        return $delegate
    ]
]
Возможно, кому-то будет интересно почитать про debounce на pure-JS, plutov.by/post/fn_delay
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории