Matt VA Developer Matt VA Developer - 20 days ago 7
AngularJS Question

What Scope is being used in Angular's $mdDialog

I have been playing around with Angular Material and I wanted to create a $mdDialog that allows a user to enter in information that when saved, will update an object tied to a ng-repeat.

While trying to get this to work and trying out different parameters for mdDialog.show() I was confused about what scope is being used when/why.

This is the first implementation:

(function () {'use strict';

angular.
module('myApp', ['ngMaterial']).
controller('AppCtrl', AppCtrl);

function AppCtrl($mdDialog, $scope) {
$scope.lister = [{name:'Matt'},{name:'Steve'}];
$scope.showDialog = showDialog;

function showDialog(evt) {
$scope.obj = {name:'default'};
$mdDialog.show({
targetEvent: evt,
scope: $scope.$new(),
template:
'<md-dialog>' +
' <md-content><md-input-container>'+
' <label>Name</label>'+
' <input ng-model="obj.name">' +
' </md-input-container></md-content>' +
' <div class="md-actions">' +
' <md-button ng-click="close(obj)">' +
' Save' +
' </md-button>' +
' </div>' +
'</md-dialog>'
}).then(function(objs){$scope.lister.unshift(objs)});
}

$scope.close = function(objs){

$mdDialog.hide(objs);
}
}

}());


The behavior of the above code is mdDialog will open with "default" in the Name input field, but if I change the show() parameters to below (key difference is swapping out "scope:" for "controller:"):

function showDialog(evt) {
$scope.obj = {name:'default'};
$mdDialog.show({
targetEvent: evt,
controller: 'AppCtrl',
template:
'<md-dialog>' +
' <md-content><md-input-container>'+
' <label>Name</label>'+
' <input ng-model="obj.name">' +
' </md-input-container></md-content>' +
' <div class="md-actions">' +
' <md-button ng-click="close(obj)">' +
' Save' +
' </md-button>' +
' </div>' +
'</md-dialog>'
}).then(function(objs){$scope.lister.unshift(objs)});
}


The behavior of the second implementation is that the mdDialog will open with a blank for the Name input field.

This is a long setup for this question: Why does the dialog template recognize $scope.obj when "scope: $scope.$new()", but it is not recognized when "controller: 'AppCtrl'"? I thought both implementations are providing AppCtrl's scope to the dialog.

Answer
  • Dialog is always given an isolated scope
  • You can pass data to dialog from parent controller using dependency injection.

function AppController($scope, $mdDialog) {
    var message='message from parent';    
    $scope.showDialog = showDialog;
    $scope.items = [1, 2, 3];
    
  
    function showDialog($event) {
       var parentEl = angular.element(document.body);
       $mdDialog.show({
         parent: parentEl,
         targetEvent: $event,
         templateUrl:'templateFile.html',
         locals: {
           items: $scope.items
         },
         message:message
         controller: DialogController
      });
      function DialogController($scope, $mdDialog, items,message) {
        $scope.items = items;
        $scope.message = message;
        $scope.closeDialog = function() {
          $mdDialog.hide();
        }
      }
}

In your first case, you are adding an object to isolated scope of your dialog using

$scope.obj = {name:'default'} and its available as obj.name on yr view.

In your second case, you are declaring controller for your dialog as 'AppCtrl', but you have not defined it anywhere inside your parent controller, so you are not getting anything on view. AppCtrl is not defined.

Comments