ErickSkrauch
@ErickSkrauch

Как решить проблему с $watch в Angular.js?

Перевожу свой проект на Angular.js, и так как дизайн требует нестандартных элементов - используются плагины. Один из них - это Selecter, для стилизации вида выпадающего меню.

Так вот, пишу директиву под это дело, получилось вот так:
app.directive("select", ['$timeout', function (timer) {
    return {
        restrict: "E",
        link: function(scope, element, attrs) {
            apply = function () {
                console.log('установили обработчик');
                $(element).selecter('destroy').selecter({
                    customClass: attrs.color
                });
            }

            init = function () {
                apply();

                if (attrs.selecterScope) {
                    console.log('Установили ватч');
                    scope.$watch(attrs.selecterScope, function () {
                        console.log('рефрешнули это дело');
                        timer(apply, 0);
                    });
                }
            }

            timer(init, 0);
        }
    };
}]);


Таймер нужен, что бы данные сначала отрендерились в:
<select ng-model="sVersion" color="green" ng-options="c for c in versions" selecter-scope="versions">
    <option value="">Выберите версию</option>
</select>

А только за тем был применён плагин.

Ошибка заключается в том, что $watch ведёт себя совершенно непонятно. Во-первых, он сразу же срабатывает в момент установки, независимо от того, изменились ли данные или нет. Во-вторых, он не отлавливает дальнейшие изменения переменной.

В переменной хранится обычный массив вида:
scope.versions = ["1.7.4", "1.7.2", "1.6.4", "1.5.2", "1.4.7"];
  • Вопрос задан
  • 5064 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
$watch всегда отрабатывает в холостую для инициализаии. Так же в вашем случае не отрабатыват dirty-checking, а потому оно не будет детектить изменения в массиве. Вам нужно либо выставить третий аргумент функции $watch в true (включает dirty-checking с копированием объектов и их сравнением) или же использовать $watchCollection.

А почему бы вместо этих извращений с ватчерами не прикрепить к select ng-model? В этом случае к слову проще будет применить изолированный скоуп, что бы избежать проблем в будущем.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы