Angular UI Modal导致无限摘要循环

Angular UI Modal causes Infinite Digest Loop

本文关键字:循环 无限 UI Modal Angular      更新时间:2023-09-26

我一直在努力创建一个允许在模式弹出窗口中检索和打开文章的系统。它已经使用Bootstrap模式成功地实现了,但由于一些新的需求,我需要转换为使用Angular UI模式。

我认为这个问题源于Angular的$location.search()对URL更改的处理,但我无法确定

由于添加了$uibModal.open()调用,每当我点击一篇文章时,就会出现这个无限摘要循环,这将在我的控制器中启动openModal函数。

我将包括我的控制器代码和我在下面收到的错误消息。控制器的两个入口点位于$rootScope的底部附近$on和$scope$观看通话。它们允许模态响应URL中的更改。

最终目标是能够在URL更改时打开Angular UI模式,这样我就可以在模式被取消时删除URL参数。

谢谢你的帮助!

我的控制器:

(function () {
    'use strict';
    //Create the LinkModalController and bind it to the core app. This makes it always available.
    angular
        .module('app.core')
        .controller('LinkModalController', LinkModalController);
    LinkModalController.$inject = ['$location', '$q', '$rootScope', '$scope', '$uibModal', 'contentpartservice', 'logger'];
    /* @ngInject */
    function LinkModalController($location, $q, $rootScope, $scope, $uibModal, contentpartservice, logger) {
        var vm = this;
        /*--------------Variable Definitions--------------*/
        vm.modalData = {};
        vm.isModalLoading = true;
        vm.selectedTab;
        vm.urlHistory;
        /*--------------Function Definitions--------------*/
        vm.selectTab = selectTab;
        vm.openModal = openModal;
        /*Activate Controller*/
        activate();
        /*--------------Functions--------------*/
        /*Announcement clicks are handled separately because the announcement data contains the full article*/
        function handleAnnouncementClick(data) {
            vm.modalData = data;
            $("#announcementModal").modal();
            return;
        }
        /*Set the active tab for the open modal*/
        function selectTab(tab) {
            vm.selectedTab = tab;
            return;
        }
        /*Clicking an article of any content type should be funneled through this function. Eventually to be merged with handleSearchResultClick*/
        function handleContentTypeClick(data) {
            setUrl(data.id, data.contentType.value);
            return;
        }
        function handleUrlParamsModalLaunch(data) {
            console.log('launching modal');
            /*Ensure modal is not displaying any data*/
            vm.modalData = {};
            vm.selectedTab = null;
            /*Show modal loading screen*/
            vm.isModalLoading = true;
            var modalInstance = $uibModal.open({
                templateUrl: 'app/modals/contentTypeModalTemplate.html',
                controller: 'LinkModalController as vm',
            });
            /*Call the content service to return the clicked content article*/
            contentpartservice.getContentItem(data.id, data.type).then(function (contentItem) {
                if (contentItem) {
                    vm.isModalLoading = false;
                    vm.modalData = contentItem;
                    return;
                } else {
                    closeModal("#contentPartModal").then(function () {
                        vm.isModalLoading = false;
                        logger.error('An error occurred while fetching content');
                    });
                    return;
                }
            }, function (error) {
                closeModal("#contentPartModal").then(function () {
                    vm.isModalLoading = false;
                    logger.error('An error occurred while fetching content');
                });
                return;
            });
        }
        /*Close a modal and return a promise object - This allows other code to be executed only after the modal closes*/
        function closeModal(modalId) {
            $(modalId).modal('hide');
            var defer = $q.defer();
            defer.resolve();
            return defer.promise;
        }
        //Function to append information to the URL required to retrieve the displayed article
        function setUrl(contentId, contentType) {
            var urlParams = $location.search();
            if (urlParams.q) {
                $location.search({ q: urlParams.q, type: contentType, id: contentId });
            } else {
                $location.search({ type: contentType, id: contentId });
            }
            console.log($location.search());
            return;
        }
        /*Route link click calls to handle different data structures*/
        function openModal(data, context) {
            switch (context) {
                case 'urlParams':
                    handleUrlParamsModalLaunch(data);
                    break;
                case 'announcement':
                    handleAnnouncementClick(data);
                    break;
                case 'contentType':
                    handleContentTypeClick(data);
                    break;
                default:
                    logger.error('An error occurred while fetching content');
            }
            return;
        }
        /*--------------Listeners--------------*/
        /*Catch links click events broadcast from the $rootScope (shell.controller.js)*/
        $rootScope.$on('openModal', function (event, data, context) {
            vm.openModal(data, context);
            return;
        });
        /*--------------Activate Controller--------------*/
        function activate() {
            /*Create a watcher to detect changes to the URL*/
            $scope.$watch(function () { return $location.search() }, function () {
                alert('url changed');
                /*Wait for modals to render*/
                var urlParams = $location.search();
                if (urlParams.type && urlParams.id) {
                    vm.openModal(urlParams, 'urlParams');
                }
                /*Handle the inital page load. (Must wait until content is loaded to open modal). This code only runs once.*/
                $rootScope.$on('$includeContentLoaded', function () {
                    alert('url changed first laod');
                    /*Wait for modals to render*/
                    var urlParams = $location.search();
                    if (urlParams.type && urlParams.id) {
                        vm.openModal(urlParams, 'urlParams');
                    }
                });
            }, true);
        }
    }
})();

记录的错误消息是一个巨大的文本块,所以我把它粘贴到了谷歌文档中:https://docs.google.com/document/d/1esqZSMK4_Tiqckm-IjObqTvMGre2Ls-DWrIycvW5CKY/edit?usp=sharing

不知道您是否在应用程序的配置模块中尝试过$locationProvider.html5Mode(true);。如果您使用jquery模型打开弹出窗口,它可能会在angular和jquery之间发生冲突,因为jquery也会监视url上的变化。我以前也有类似的问题。