1

I have been using angular-ui with angularjs for a while now and have encountered a problem and subsequently a solution, but I want to know if this is a good way to do things. The original issue was dealing with passing objects in a directive's scope to a modal. Most of the suggestions I found on SO and such deal with resolve:

resolve: members that will be resolved and passed to the controller as locals: AngularJS - Pass object data into modal

My issue with the suggestions was that if you need to pass different objects from the scope to the modal for different modals, you will need two controllers per modal. One with the open() method/$modal service and the other for the actual $modalinstance. This is due to the necessity of resolving different objects in different ways for different modals. I decided that instead of using multiple resolves, why not use one that is an object that can be defined in the html to hold all of the other objects in the directive's scope that you wish to pass to the modal?

The code is below - everything should look fairly vanilla until the test.html directive template.

app.js:

var app = angular.module('modalscope', ['ui.bootstrap']);

app.controller('ModalCtrl', function($scope, $modal){

    $scope.open = function(modal_scope){
        var modalInstance = $modal.open({
            scope: $scope,
            templateUrl: 'modal-content.html',
            controller: 'ModalInstanceCtrl',
            resolve: {
                modal_scope: function() {
                        $scope.modal_scope = modal_scope;
                        return $scope.modal_scope;
                }
            }
        });
    };
});

app.controller('ModalInstanceCtrl', function($scope, $modalInstance, modal_scope){
    $scope.names = modal_scope.names;
    $scope.selName = modal_scope.selName;
    $scope.ok = function(){
        $modalInstance.close({  });
    };
});

app.directive("appList", function() {
  return {
    restrict: 'E',
    templateUrl: "test.html",
    'link': function(scope, iElement, iAttrs) {
            scope.names = [ {"name":"john"},{"name":"joe"},{"name":"mary"}];
    }
  };
});

index.hmtl:

<html ng-app="modalscope">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="app.js"></script>


</head>
<body>
    <app-list></app-list>
</body>
</html>

test.html:

<div ng-controller="ModalCtrl">
    <h2 ng-repeat="name in names">{{name.name}}<button ng-click="open({'names':names,'selName':name });">Click</button></h2>
</div>

modal_content.html:

<h2>modal test</h2>
<p>name: {{selName.name}}</p>
<button class="btn btn-success" ng-click="ok()">OK</button>

Basically, is my current implementation going to cause issues? Are there better ways to avoid writing multiple controllers per modal/resolving a long list of potential scope objects than resolving a single container object for the modal instance's scope as I did with:

"open({'names':names,'selName':name });"
3
  • 1
    resolve will not pass scope, it is passed as dependency to the target controller. In order to set scope, you could just make use of scope property of the settings, which you already are doing. You could create a new scope using var modalScope = $scope.$new(); modalScope.prop = "val"; //etc and set scope: modalScope, in the settings. Commented Sep 26, 2014 at 18:34
  • I tried to just use scope: $scope, but the values were not accessible in the modal instance without the resolve statement. Is passing the dependency from resolve required? Or is there a different way to pass the scope from the directive to the modal? Commented Sep 26, 2014 at 19:09
  • The other problem I ran into was trying to access the 'name' in the ng-repeat from the modal. That is why I passed selName to the modal controller in modal_scope object. Is there a better way? Commented Sep 26, 2014 at 19:22

1 Answer 1

-1

I know this is an old question but I landed here from Google so others might. Here's how I would transfer a large number of values into a modal without using resolve:

app.controller('ModalCtrl', function($scope, $uibModal, $rootScope) {

    $scope.open = function(options) {
        // Make a brand new scope for the modal. Alternatively you could use
        // $scope.$new() to get a new scope which inherits from the controller's
        // scope.
        var modal_scope = $rootScope.$new();

        // Copy data from the options into the new scope (depending on what's in
        // options you may want to use a clone of options to get a completely
        // separate copy, or angular.merge).
        angular.extend(modal_scope, options);

        return $uibModal.open({
            // Use the new scope as the modal's scope
            scope: modal_scope,
            templateUrl: 'modal-content.html',
            controller: 'ModalInstanceCtrl',
            // No need for any resolves
        });
    };
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.