Сервисы AngularJS теряют данные

У меня есть 4 директивы, все обращаются к одному и тому же сервису 'checkoutData'. Первые 3 директивы загружают сервис checkoutData данными (информация о доставке и оплате). Когда я отлаживаю, я вижу, что они совместно используют один и тот же экземпляр, потому что данные присутствуют для всех 3. 4-я директива (continueCheckout) отвечает за проверку правильности всех данных перед выполнением других действий. Проблема в том, что данные службы checkoutData тогда пусты. Я могу установить точку останова в первой строке checkoutData и увидеть, что она вызывается только один раз, поэтому я знаю, что существует только 1 экземпляр. Что происходит?

Продолжить оформление заказа

(function() {
    angular.module('checkoutApp').directive('continueCheckout', function() {
        return {
            restrict: 'E',
            scope: {
                'nextStep': '@',
                'buttonText': '@'
            },
            template: '<a href ng-click="validate()"><button type="submit" class="btn btn-default">{{buttonText}}</button></a>',
            controller: function ($scope, $location, $log, checkoutData) {
                checkoutData.printData();
                $scope.validate = function () {
                    checkoutData.printData();
                    if (checkoutData.isValid()) {
                        $location.path("/" + $scope.nextStep);
                    }
                }
            }
        }
    });
})();

checkoutData.js

(function() {
    angular.module('checkoutApp').factory('checkoutData', ['$log', function($log) {
        var data = {
            shippingOptionId: null,
            billingOptionId: null,
            shipping: {},
            billing: {}
        };
        var inputForms = [];
        var printData = function () {
            $log.debug(JSON.stringify(inputForms));
            $log.debug(JSON.stringify(data.shipping));
            $log.debug(data.shippingOptionId);
        };
        var isValid = function() {
            printData();
            return false;
            //return _.every(data.inputForms, function(form) { return form.valid });
        };
        return {
            shipping: data.shipping,
            setValid: function(formName, valid) {
                inputForms[formName].valid = valid;
            },
            initializeForm: function(formName) {
                inputForms[formName] = {};
            },
            isValid: isValid,
            printData: printData
        }
    }]);
})();

ShippingOptions.js (одна из директив, которая работает и может видеть данные оформления заказа)

(function() {
    angular.module('checkoutApp').directive('shippingOptions', function() {
        return {
            restrict: 'E',
            templateUrl: 'Scripts/Checkout/ShippingOptions/shippingOptions.html',
            controller: function ($scope, $log, shippingOptionsService, checkoutData) {
                $scope.selectedShippingOption = {};
                $scope.checkoutData = checkoutData;
                checkoutData.initializeForm('shippingOptions');
                $scope.$watch('shippingOptionsForm.$valid', function (newVal) {
                    checkoutData.setValid('shippingOptions', newVal);
                });
                $scope.$watch('selectedShippingOption', function (newVal) {
                    checkoutData.selectedShippingId = newVal;
                });
                $scope.shippingOptions = [
                    { id: 1, name: 'UPS Ground', cost: '11.32', display: 'UPS Ground ($11.32)', moreInfo: 'ups ground more info' },
                    { id: 2, name: 'UPS 3 Day', cost: '17.92', display: 'UPS 3 Day ($17.92)', moreInfo: 'ups 3 day more info' },
                    { id: 3, name: 'UPS 2 Day', cost: '20.76', display: 'UPS 2 Day ($20.76)', moreInfo: 'ups 2 day more info' }
                ];
            }
        }
    });
})();

1 ответ

Решение

Проблема в том, что функция isValid обрабатывает data.inputForms как массив. Он загружается как ассоциативные объекты (сбор значений ключей), поэтому его нельзя перебрать с помощью.forEach. Вот рабочий код для isValid()

var isValid = function () {
    for (var key in data.inputForms) {
        if (data.inputForms.hasOwnProperty(key)) {
            if (!data.inputForms[key].valid) {
                return false;
            }
        }
    }
    return true;
};
Другие вопросы по тегам