JackTheKnife JackTheKnife -3 years ago 146
AngularJS Question

AngularJS - moving Material mdDialog to service

I'm trying to cleanup code of one of my controllers which became too big. First I have decided to move attendee registration, which uses AngularJS Material mdDialog, to the service.

Original (and working) controller code looks like:

myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog){

var attendee = this;
attendees = [];
...

$scope.addAttendee = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'attendee',
fullscreen: $scope.customFullscreen, // Only for -xs, -sm breakpoints.
locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);

console.log(attendees);
console.log(attendees.length);
})
};

function DialogController($scope, $mdDialog) {

var attendee = this;

$scope.hide = function() {
$mdDialog.hide();
};

$scope.cancel = function() {
$mdDialog.cancel();
};

$scope.save = function(response) {
$mdDialog.hide(response);
};
}

}]);


and the code for the controller after separation:

myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog','Attendees', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog, Attendees){

...


$scope.attendees= Attendees.list();

$scope.addAttendee = function (ev) {
Attendees.add(ev);
}

$scope.deleteAttendee = function (id) {
Attendees.delete(id);
}

}]);


New service code looks like:

myApp.service('Attendees', ['$mdDialog', function ($mdDialog) {
//to create unique attendee id
var uid = 1;

//attendees array to hold list of all attendees
var attendees = [{
id: 0,
firstName: "",
lastName: "",
email: "",
phone: ""
}];

//add method create a new attendee
this.add = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'attendee',
fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
//locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);

console.log(attendees);
console.log(attendees.length);
})
};

//simply search attendees list for given id
//and returns the attendee object if found
this.get = function (id) {
for (i in attendees) {
if (attendees[i].id == id) {
return attendees[i];
}
}

}

//iterate through attendees list and delete
//attendee if found
this.delete = function (id) {
for (i in attendees) {
if (attendees[i].id == id) {
attendees.splice(i, 1);
}
}
}

//simply returns the attendees list
this.list = function () {
return attendees;
}

function DialogController($mdDialog) {

this.hide = function() {
$mdDialog.hide();
};

this.cancel = function() {
$mdDialog.cancel();
};

this.save = function(response) {
$mdDialog.hide(response);
};
}

}]);


but I'm not able to "save" from the spawned mdDialog box which uses
ng-click=save(attendee)
neither close the dialog box.

What I'm doing wrong?

Answer Source

I'm not able to "save" from the spawned mdDialog box which uses ng-click=save(attendee) neither close the dialog box.

When instantiating a controller with "controllerAs" syntax, use the name with which it is instantiated:

<button ng-click="ctrl.save(ctrl.attendee)">Save</button>
this.add = function(ev) {
    $mdDialog.show({
    controller: DialogController,
    templateUrl: 'views/regForm.tmpl.html',
    parent: angular.element(document.body),
    targetEvent: ev,
    clickOutsideToClose:true,
    controllerAs:  ̶'̶a̶t̶t̶e̶n̶d̶e̶e̶'̶ 'ctrl',
    fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
    //locals: {parent: $scope}
})
.then(function(response){
    attendees.push(response);

    console.log(attendees);
    console.log(attendees.length);
    return response;     
});

To avoid confusion, choose a controller instance name that is different from the data names.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download