@matios
Technical Team Lead

Как отрисовать значение таймера, реализованного через сервис, без передергивания всего скоупа?

Всем привет. Есть желание вывести несколько счетчиков countdown на старице с помощью ангуляра. Для этого я написал сервис: https://jsfiddle.net/j2wz86m2/ который будет делать все расчеты и отдавать нужный результат для каждого счетчика. На первый взгляд все работает хорошо, но я заметил очень серьезную проблему, которая потенциально может привести к выжиранию большого кол-ва памяти. Итак, что я делаю:
1. В контроллер внедряю зависимость от данного сервиса $counterService
2. Запускаю каждый счетчик:
$counterService.getInstance('counter' + id).startCounter(data.end);

3. В контролере создаю метод для получение значения счетчика по его названию:
$scope.getCounter = function(counterName) {
    $counterService.getInstance(counterName).counterValue();
}


Но в данном случае возникает следующая проблема:
По скольку $timer после выполнения колбека запускает дигест, то данные всех счетчиков корректно отрисовываются в DOM, но помимо вызова метода getCounter() вызываются еще все методы скоупа, что меня крайне не устраивает. Ведь мне не нужно вызывать все методы, мне нужно вызвать только 1 для получения нового значения счетчика. А поскольку вызываются все методы скоупа, то это приводит к повышенному расходу памяти. Я знаю, что $timer принимает третий параметр, которым можно отключить запуск дигеста, но в таком случае таймеры тикают, но на странице не обновляются.

Можно ли как-либо корректно отрисовывать значения таймеров, при этом не вызывая лишних методов скоупа?

PS. Рабочий пример можно посмотреть тут: https://jsfiddle.net/j2wz86m2/6/ (в консоль падает то, что не должно попадать при обновлении счетчиков)

UPD. Я так подозреваю, что интересующее меня решение выбивается из концепции ангуляра. Идея @jackkum навела меня на мысль, что можно получать значение в директиве и отрисовывать значение с помощью jQuery html() или text(), что конечно выбивается из концепции ангуляра, да и 2 таймаута - не самое хорошее решение, но тем не менее работает должным образом. В итоге финальный вариант получился таким:
https://jsfiddle.net/j2wz86m2/7/

Если есть идеи получше, буду рад взглянуть
Отдельное спасибо @jackkum за наводку
  • Вопрос задан
  • 219 просмотров
Решения вопроса 1
Можно сделать каждый счетчик в разных контроллерах, но это не очень удобно.
Можно сделать директиву plnkr.co
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы