ps0604
ps0604

Reputation: 1081

Integrating directive in Angular UI Modal

In this plunk I have the following:

For some reason the control object is empty when the modal is opened (look at the console log). How to invoke the method from the controller to set the field value?

HTML

<div ng-app="app" ng-controller="myCtl">

        <button ng-click="openModal()">Open modal</button>

        <script type="text/ng-template" id="myModalContent.html">

            <div class="modal-header">
                <h4 class="modal-title">The Title</h4>
            </div>

            <ddl control="ddlControl"></ddl>                

            <div class="modal-footer">
                <button type="submit">Submit</button>
            </div>

       </script>

    </div>

Javascript

var app = angular.module('app', ['ui.bootstrap']);
app.controller('myCtl', function($scope,$uibModal) {

        $scope.ddlControl = {};

        $scope.openModal = function() {
          $scope.modalInstance = $uibModal.open({
              templateUrl: 'myModalContent.html',
              scope: $scope
            }); 

          console.log($scope.ddlControl);
          $scope.ddlControl.set();

        };
})

.directive('ddl', function () {

    var directive = {};
    directive.restrict = 'EA';
    directive.scope = {
         control: '='
    };
    directive.template = '<div>someValue: {{someValue}}</div>';
    directive.link = function (scope, element, attrs) {

        scope.control = scope.control || {};

        scope.control.set = function() {
           scope.someValue = 1;
        };

    };
    return directive;
});

Upvotes: 1

Views: 3220

Answers (1)

com2ghz
com2ghz

Reputation: 2876

There is a race condition between opening the modal and running a digest of the modal HTML.

When the button is clicked $scope.openModal() is executed. The modal opens and gets into the digest phase. But javascript is not waiting until the digesting has been completed, so it continues executing $scope.openModal() until the end.

You need to handle the promise of $uibModal.open().rendered(). The uibModal resolves the rendered promise when it's done.

    $scope.openModal = function() {
      $scope.modalInstance = $uibModal.open({
          templateUrl: 'myModalContent.html',
          scope: $scope
        }).rendered.then(function() {
             console.log($scope.ddlControl);
             $scope.ddlControl.set(); 
        }); 
    };

The $uibModal.open() function returns the following:

Object {result: Promise, opened: Promise, rendered: Promise}

In the promise block of rendered, you can safely make use of the fields that has been changed by the directive.

Plunker: http://plnkr.co/edit/GnIThstxkuR06felh8Pe?p=preview

Upvotes: 5

Related Questions