Tuesday, February 10, 2015

Angular Dialog

If you're using Angular you've probably come across a situation where you wanted to take some action on one scope from a different scope.  In the specific situation I was faced with today I had one scope (scope A) launching a jQuery UI dialog and the contents of the dialog contained a second scope (scope B).  My problem was that the dialog contents included a Close button that called a function that existed on scope B and I needed that event to also get called if the built-in close button (the X in the upper right-hand corner of the dialog) was used to close the dialog.  Eventually I realized that I also needed that event to get called if the user pressed the <Esc> key to close the dialog.

Although I'm sure there are lots of ways to do this, I ended up using jQuery to retrieve scope B and invoke the desired function.  Some sample code:

$scope.OpenDialogWithChildScope = function () {
    $("#dialogWithChildScope").dialog({
        width: 800,
        height: 750,
        title: "Child Scope Dialog",
        modal: true,
        closeOnEscape: true,
        open: function (event, ui) {
            // store the current object (before any changes) in a separate object
            repository.OriginalItem = angular.copy(repository.CurrentItem);
        },
        close: function () {
            // get the scope of the dialog
            var scope = angular.element("[ng-controller='childScopeController']").scope();
            // clear the errors from the dialog so it's clean the next time it opens
            scope.ClearDialogErrors();
            // check whether the contents of the dialog need to be refreshed
            // (because some change was made and that change should be reflected on scope A)
            if (repository.ShouldRefresh) {
                // refresh scope A
                repository.refresh().then(function(results) {
                    // set the item on scope A, reset the pre-changed object, reset the refresh variable
                    repository.CurrentItem = results;
                    repository.OriginalItem = null;
                    repository.ShouldRefresh = false;
                });
            } else {
                // if the contents don't need to be refreshed, replace the contents with the pre-changed object
                // in order to undo any changes that were made but not saved while the dialog was open
                repository.CurrentItem = angular.copy(repository.OriginalItem);
                repository.OriginalItem = null;
            }
        },
        position: {
            my: "center center",
            at: "center center",
            of: $("#body"),
            collision: "fit fit"
        }
    });
};

No comments:

Post a Comment