Попытка $ Смотреть переменную из изолированной области видимости

0

Новое для создания пользовательских директив. Он отлично отображает начальную визуализацию. Тем не менее, я пытаюсь $watch за изменениями исходных данных, а затем запускать обновление.

В качестве быстрого теста я создал кнопку и использовал jQuery для обновления массива costPerDay.costs (вручную)... но часы $ watch все еще не срабатывают, и моя точка останова не была достигнута.

Спасибо за помощь...

МОЙ КОНТРОЛЛЕР СМОТРЕТЬ КАК:
GET издевается, чтобы вернуть объект, а не обещание, поэтому игнорируйте эту конкретную строку. Как только я получу часы $ watch, я обновлю эту часть кода соответственно.

// CONTROLLER
application.controller('HomeIndexController', function ($scope, costPerDayDataService) {
    var vm = this;

    // Internal
    vm.on = {
        databind: {
            costPerDay: function () {
                // The GET is mocked to return an object, not a promise, so ignore this line
                var costPerDay = costPerDayDataService.get();
                $scope.data.costPerDay = costPerDay;
            }
        }
    };
    vm.databind = function () {
        vm.on.databind.costPerDay();
    };

    // Scope
    $scope.data = {
        costPerDay: {}
    };

    $scope.on = {
        alterCosts: function (e) {
            var costs = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300];
            $scope.data.costPerDay.costs = costs;
        }
    }

    // Databind
    vm.databind();
});

МОЙ ЭЛЕМЕНТ СМОТРЕТЬ КАК:
Вначале это делает штраф. Мне нужно автоматизировать обновления.

<ul id="sparks" class="pull-down pull-left">
    <li cost-per-day-sparkline costperday="data.costPerDay">
    </li>
</ul>

МОЙ ДИРЕКТИВ СМОТРЕТЬ КАК:
Я просто пытаюсь заставить ОДИН из них работать... Я, очевидно, удалю остальных, когда получу рабочий пример. И да, я знаю, что вы НЕ должны обновлять $parent напрямую. Я просто пытаюсь найти комбинацию, которая работает до того, как я получу фантазию.

define([], function () {
    'use strict';

    function CostPerDaySparklineDirective() {
        return {
            replace: true,
            restrict: "AE",
            scope: {
                costperday: "=costperday"
            },
            templateUrl: '/modules/templates/sparklines/costperdaysparklinetemplate.html',
            link: function (scope, elem, attrs) {


                // This fails       
                scope.$watch('costperday', function (newval) {
                    // ... code to update will go here
                }, true);

                // This fails           
                scope.$watch('costperday', function (newval) {
                    // ... code to update will go here
                });

                // This fails
                scope.$parent.$watch('data.costPerDay.costs', function (newval) {
                    // ... code to update will go here
                });

                // This renders initially, but fails to fire again
                scope.$watch('scope.$parent.data.costPerDay.costs', function (newval) {
                    var eleSparkline = $('.sparkline', elem);
                    eleSparkline.sparkline(scope.costperday.costs, { type: "bar" });
                });
            }
        };
    }

    return CostPerDaySparklineDirective;
});

ОБНОВИТЬ:
Даже используя ng-click для проверки $ watch не удается попасть в точку останова...

<a ng-click="on.alterCosts()">Change Costs</a>
  • 1
    Попробуйте обновить массив costPerDay.costs из угловой функции вместо jQuery, чтобы проверить, нет ли проблемы с дайджестом области или нет. Возможно, проблема в том, что переменная costPerDay.costs выйдет из области видимости.
  • 0
    @krish Я думал, что $ watch «слушал» изменения области видимости (очень похоже на наблюдаемые). Я ошибаюсь? Я бы «подумал», что если бы это было заметно, то КАК вы меняете цель наблюдения, это не имеет значения ... но это может быть неверно.
Показать ещё 3 комментария
Теги:
angularjs-directive

2 ответа

1
Лучший ответ

В этом случае я бы запускал $scope.$apply(); в вашем методе alterCosts чтобы вызвать дайджест шаблона. Это обновит значение в DOM, которое ваша директива поймает, а затем запускает $ watch.

Для получения дополнительной информации о $apply(), https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ apply

"$ apply() используется для выполнения выражения в угловом формате вне рамок (например, из событий браузера DOM.."

В этом конкретном сценарии вы меняете значение из события DOM.

  • 0
    Вы ВСЕГДА должны вручную вызывать дайджест?
  • 0
    Если я использую ng-click ... как это считается "вне угловых рамок"?
Показать ещё 1 комментарий
1

в этой ситуации я бы посмотрел фактический получение costPerDayDataService и прослушивание переменной области контроллеров. поэтому в вашем контроллере вы должны "установить" переменную в costPerDayDataService, и в вашей директиве вы просто вводите свою услугу и смотрите функцию get. ИЛИ, если вы используете 1.3.x>, вы можете использовать bindToController, который, я считаю, устраняет всю потребность в часах.

bindToController: {
  costperday: '='
}
  • 0
    +1 ... я обязательно попробую это. Сейчас я просто экспериментирую с тестовым приложением (пытаюсь научиться).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню