AngularJs Factory - 视图控制器中不存在数据

时间:2015-01-08 11:54:55

标签: angularjs factory

我创建了一些角度的factorys,它们存储了一些数据并提供了一些方法。如果我的应用程序视图发生了变化,我将检查是否在factorys中存在某些数据,以及是否允许根据数据显示该视图。

在方法中,我可以调用另一个工厂的方法。 $ basket.getBasketTotal()。value - >此方法返回空值而没有延迟。该值存储在工厂的属性中。 $ basket工厂具有与$ bookingSteps相同的结构,它只包含其他值。

如果我从视图控制器调用工厂方法,似乎工厂的数据不存在。如果我调试它,则存在数据,因为调试会使执行速度变慢。所以对我而言,问题似乎与生命周期和工厂状态有关。

如果我将$ timeout arround包装并且延迟调用工厂方法,那么app的行为就像预期的那样。但这不是一个很好的解决方案。

有人知道如何解决这种问题吗?

 app.controller('checkoutController', ['$scope', '$timeout', '$bookingStepsFactory', function ($scope, $timeout, $bookingStepsFactory) {
        $timeout(function () {
            $bookingStepsFactory.isAssessable();
        }, 1500);



    }]);


app.factory('$bookingStepsFactory', ['$rootScope', '$route', '$location', '$rateSearchFactory', '$global', 'localStorageService', '$basket',
        function ($rootScope, $route, $location, $rateSearchFactory, $global, localStorageService, $basket) {

            /**
             * Stored the current visible booking step, the number of maximum steps available
             * and the routes for each step
             * @type {{currentStep: number, maxSteps: number, routes: Array}}
             */
            var bookingStepsSettings = {
                currentStep: 1,
                maxSteps: 5,
                routes: []
            }, numberOfProperties = 0, tmpMaxStepsFromRoutes = 0, key;

            //Number of hotels within this channel type
            numberOfProperties = $global.getHotelData().length;


            for (key in $route.routes) {
                if ($route.routes.hasOwnProperty(key)) {
                    if ($route.routes[key].bookingStep) {

                        //Find the highest step number within routes
                        if (tmpMaxStepsFromRoutes === 0) {
                            tmpMaxStepsFromRoutes = $route.routes[key].bookingStep;
                        } else if ($route.routes[key].bookingStep > tmpMaxStepsFromRoutes) {
                            tmpMaxStepsFromRoutes = $route.routes[key].bookingStep;
                        }

                        //If the minimum number of results needed for the route is lower than the number of hotels,
                        //add route to collection. If there is only one hotel, all routes needing mor than one result, will
                        //not be added. i.e. The hotel selection is not needed for one hotel.

                        if (!$route.routes[key].disabled && $route.routes[key].minResults && $route.routes[key].minResults <= numberOfProperties) {
                            bookingStepsSettings.routes.push({
                                step: $route.routes[key].bookingStep,
                                path: key,
                                minResults: $route.routes[key].minResults,
                                name: $route.routes[key].stepName,
                                disabled: $route.routes[key].disabled || false,
                                needItemsInBasket: $route.routes[key].needItemsInBasket || false
                            });
                        } else if (!$route.routes[key].disabled && !$route.routes[key].minResults) {
                            bookingStepsSettings.routes.push({
                                step: $route.routes[key].bookingStep,
                                path: key,
                                minResults: $route.routes[key].minResults,
                                name: $route.routes[key].stepName,
                                disabled: $route.routes[key].disabled || false,
                                needItemsInBasket: $route.routes[key].needItemsInBasket || false
                            });
                        }
                    }
                }
            }
            bookingStepsSettings.maxSteps = tmpMaxStepsFromRoutes;

            function save() {
                localStorageService.set('bookingStepsSettings', bookingStepsSettings);
                localStorageService.set('numberOfProperties', numberOfProperties);
            }

            function init() {
                var  date = localStorageService.get('rateDate'), obj,
                    currentDate = new Date();

                if (date) {
                    if (new Date(parseInt(date, 10)).getTime() + (5 * 60 * 1000) >= currentDate.getTime()) {
                        bookingStepsSettings = localStorageService.get('bookingStepsSettings');
                        numberOfProperties = parseInt(localStorageService.get('numberOfProperties'));
                    }
                    var current = $route.current.$$route.originalPath, numberOfSearchResults = $rateSearchFactory.resultsAvailable(), i = 0;
                    for (i = 0; i < bookingStepsSettings.routes.length; i++) {
                        if (bookingStepsSettings.routes[i].path === current) {
                            bookingStepsSettings.currentStep = bookingStepsSettings.routes[i].step;

                        }
                    }
                }
            }

            init();
            /**
             * Function that returns a route based on the step number
             * @param step (integer value between 1 and maxSteps)
             * @returns {*}
             */
            function getPath(step) {
                var i = 0, result;
                for (i = 0; i < bookingStepsSettings.routes.length; i++ ) {
                    if (bookingStepsSettings.routes[i].step === step) {
                        result = bookingStepsSettings.routes[i];
                    }
                }
                return result;
            }

            /**
             * Function that returns a route based on the min results. This is needed in case we get one result
             * in a channel with multiple hotels, to ignore the hotel selection
             * @param results
             * @returns {*}
             */
            function getStepByMinResults (results) {
                var i = 0, result;
                if (results === 0) {
                    for (i = 0; i < bookingStepsSettings.routes.length; i++ ) {
                        if (bookingStepsSettings.routes[i].bookingStep === 1) {
                            result = bookingStepsSettings.routes[i];
                            break;
                        }

                    }
                } else {


                    for (i = 0; i < bookingStepsSettings.routes.length; i++) {
                        if (bookingStepsSettings.routes[i].minResults <= results) {
                            result = bookingStepsSettings.routes[i];
                            break;
                        }
                    }
                }
                return result;
            }

            /**
             * If location will change, check if the new URL is part of the booking steps. If yes, update the current
             * booking step.
             */
            $rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
                for (var i= 0; i < bookingStepsSettings.routes.length; i++) {
                    if (newUrl.indexOf(bookingStepsSettings.routes[i].path) >= 0) {
                        if (bookingStepsSettings.routes[i].step) {
                            bookingStepsSettings.currentStep = bookingStepsSettings.routes[i].step;
                        }
                    }
                }
            });


            /**
             * This functions are needed to navigate to the next or previous booking step.
             * They are used i.e. by the search box, booking progress
             */
            return {

                /**
                 * Is used to navigate to the next booking step
                 */
                nextStep: function () {
                    if (bookingStepsSettings.currentStep < bookingStepsSettings.maxSteps) {
                        var numberOfSearchResults = $rateSearchFactory.resultsAvailable(), tmpStep;
                        tmpStep = getPath(bookingStepsSettings.currentStep + 1);
                        if (tmpStep.needItemsInBasket && $basket.getBasketTotal().value < 1) {
                            return;
                        }
                        if (tmpStep.minResults) {
                            if (tmpStep.minResults <= numberOfSearchResults) {
                                bookingStepsSettings.currentStep = tmpStep.step;
                                $location.path(tmpStep.path);
                            } else {
                                tmpStep = getStepByMinResults(numberOfSearchResults);
                                bookingStepsSettings.currentStep = tmpStep.step;
                                $location.path(tmpStep.path);

                            }
                        } else {
                            $location.path(tmpStep.path);
                        }

                    }
                    save();
                },
                isAssessable: function() {
                    var current = $route.current.$$route.originalPath, numberOfSearchResults = $rateSearchFactory.resultsAvailable(), i = 0;
                    for (i = 0; i < bookingStepsSettings.routes.length; i++) {
                        if(bookingStepsSettings.routes[i].path === current) {
                            if (bookingStepsSettings.routes[i].needItemsInBasket && $basket.getBasketTotal().value < 1) {
                                $location.path(getPath(1).path);
                            }
                            if (bookingStepsSettings.routes[i].minResults) {
                                if (bookingStepsSettings.routes[i].minResults > numberOfSearchResults) {
                                    $location.path(getPath(1).path);
                                }
                            }

                        }
                    }
                },
                /**
                 * Is used to navigate to the previous booking step
                 */
                previousStep: function () {
                    if (bookingStepsSettings.currentStep < bookingStepsSettings.maxSteps) {
                        bookingStepsSettings.currentStep --;
                        $location.path(getPath(bookingStepsSettings.currentStep));
                    }
                    save();
                },
                /**
                 * Is used to navigate to a specific booking step
                 * @param step (Integer between 1 and maxSteps)
                 */
                goToStep: function (step) {
                    if (step < bookingStepsSettings.maxSteps) {
                        var numberOfSearchResults = $rateSearchFactory.resultsAvailable(), tmpStep;
                        tmpStep = getPath(step);
                        if (tmpStep) {
                            if (tmpStep.needItemsInBasket && $basket.getBasketTotal().value < 1) {
                                return;
                            }
                            if (!tmpStep.minResults || tmpStep.minResults && tmpStep.minResults <= numberOfSearchResults) {
                                bookingStepsSettings.currentStep = tmpStep.step;
                                $location.path(tmpStep.path);
                            } else {
                                tmpStep = getStepByMinResults(numberOfSearchResults);
                                bookingStepsSettings.currentStep = tmpStep.step;
                                $location.path(tmpStep.path);

                            }
                        }

                    }
                    save();

                },
                /**
                 * This function returns a copy of all routes within the booking steps.
                 * @param step (Integer value between 1 and maxSteps)
                 * @returns {*} Copy of a route object
                 */
                getBookingRoutes: function () {
                   return angular.copy(bookingStepsSettings.routes);
                },
                getCurrentStep: function () {
                    return angular.copy(bookingStepsSettings.currentStep);
                }
            };


        }]);

0 个答案:

没有答案