Angular UI Bootstrap Modal - how to prevent multip

2019-03-27 12:02发布

问题:

I've implemented the modal directive, and set the $modal.open option backdrop to false. However, now I can trigger multiple modals to open. Is there a way to prevent the trigger button from firing once one modal is open?

var accountSummaryCtrl = function ($scope, $modal, $log) {

    $scope.open = function () {

        var modalInstance = $modal.open({
            templateUrl: '/Apps/generic/modal/Templates/AccountSummary.html',
            controller: ModalInstanceCtrl,
            backdrop: false
        });

        modalInstance.result.then(function (selectedItem) {
            $scope.selected = selectedItem;
        }, function () {
            $log.info('Modal dismissed at: ' + new Date());
        });
    };
};

Thanks

回答1:

Use a boolean flag to avoid it:

var accountSummaryCtrl = function ($scope, $modal, $log) {

    var opened = false;

    $scope.open = function () {

        if (opened) return;

        var modalInstance = $modal.open({
            templateUrl: '/Apps/generic/modal/Templates/AccountSummary.html',
            controller: ModalInstanceCtrl,
            backdrop: false
        });

        opened = true;

        modalInstance.result.then(function (selectedItem) {
            $scope.selected = selectedItem;
            opened = false;
        }, function () {
            $log.info('Modal dismissed at: ' + new Date());
            opened = false;
        });
    };
};


回答2:

I've made a simple directive which uses same technique as in J. Bruni's answer.

/**
 * Directive which helps to prevent multiple modals opened when clicking same button many times.
 *
 * Just replace "ng-click" with "open-single-modal" in your html. Example:
 *
 * <button open-single-modal="openModal()">Open Window</button>
 *
 * NOTICE! "openModal()" function must return modalInstance which is a result of "$uibModal.open()"
 */
app.directive('openSingleModal', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var opened = false;

            element.bind('click', function () {
                if(opened) {
                    return;
                }

                opened = true;
                var modalInstance = scope.$eval(attrs.openSingleModal);

                if(!modalInstance || !modalInstance.result || typeof modalInstance.result.then !== 'function') {
                    console.error('Incorrect modal instance returned from the open modal function', element, modalInstance);
                    return;
                }

                modalInstance.result.then(function () {
                    opened = false;
                }, function () {
                    opened = false;
                });
            });
        }
    };
});

To switch your code for this directive just change "ng-click" to "open-single-modal" and the function fired by ng-click must return modal instance.

Example. Before:

<a ng-click="openModal()">Open Me!</a>

After:

<a open-single-modal="openModal()">Open Me!</a>

and

$scope.openModal = function() {
    return $uibModal.open(...);
};


回答3:

J Bruni's answer is very good, but instead of using an additional variable, use what you already have with modalInstance. Since you declare modal instance higher up, you also gain flexibility to use that variable elsewhere (such as for when you may want to dismiss the dialog).

    link: function(scope, element, attrs) {
        var modalInstance;        /*assign to undefined if you like to be explicit*/

        element.bind('click', function () {
            if(modalInstance) {
                return;
            }

            modalInstance = scope.$eval(attrs.openSingleModal);

            if(!modalInstance || !modalInstance.result || typeof modalInstance.result.then !== 'function') {
                console.error('Incorrect modal instance returned from the open modal function', element, modalInstance);
                return;
            }

            modalInstance.result.then(function () {
                modalInstance = undefined;
            }, function () {
                modalInstance = undefined;
            });
        });
    }