(js) Make use of 'controllerAs' in Mailer module

This commit is contained in:
Francis Lachapelle
2015-07-13 15:22:58 -04:00
parent 7c6716784e
commit aee229e700
12 changed files with 543 additions and 503 deletions

View File

@@ -33,7 +33,8 @@
views: {
mailboxes: {
templateUrl: 'UIxMailMainFrame', // UI/Templates/MailerUI/UIxMailMainFrame.wox
controller: 'MailboxesController'
controller: 'MailboxesController',
controllerAs: 'app'
}
},
resolve: {
@@ -45,7 +46,7 @@
abstract: true,
views: {
mailbox: {
template: '<ui-view/>',
template: '<ui-view/>'
}
},
resolve: {
@@ -57,7 +58,8 @@
views: {
'mailbox@mail': {
templateUrl: 'UIxMailFolderTemplate', // UI/Templates/MailerUI/UIxMailFolderTemplate.wox
controller: 'MailboxController'
controller: 'MailboxController',
controllerAs: 'mailbox'
}
},
resolve: {
@@ -65,12 +67,26 @@
stateMessages: stateMessages
}
})
.state('mail.account.mailbox.newMessage', {
url: '/new',
views: {
'mailbox@mail': {
templateUrl: 'UIxMailEditor', // UI/Templates/MailerUI/UIxMailEditor.wox
controller: 'MessageEditorController',
controllerAs: 'editor'
}
},
resolve: {
stateMessage: stateNewMessage
}
})
.state('mail.account.mailbox.message', {
url: '/:messageId',
views: {
message: {
templateUrl: 'UIxMailViewTemplate', // UI/Templates/MailerUI/UIxMailViewTemplate.wox
controller: 'MessageController'
controller: 'MessageController',
controllerAs: 'viewer'
}
},
resolve: {
@@ -82,7 +98,8 @@
views: {
'mailbox@mail': {
templateUrl: 'UIxMailEditor', // UI/Templates/MailerUI/UIxMailEditor.wox
controller: 'MessageEditorController'
controller: 'MessageEditorController',
controllerAs: 'editor'
}
},
resolve: {
@@ -94,25 +111,10 @@
views: {
'mailbox@mail': {
templateUrl: 'UIxMailEditor', // UI/Templates/MailerUI/UIxMailEditor.wox
controller: 'MessageEditorController'
controller: 'MessageEditorController',
controllerAs: 'editor'
}
}
})
.state('mail.newMessage', {
url: '/new',
views: {
mailbox: {
templateUrl: 'UIxMailEditor', // UI/Templates/MailerUI/UIxMailEditor.wox
controller: 'MessageEditorController'
}
},
resolve: {
stateMessage: ['stateAccounts', function(stateAccounts) {
if (stateAccounts.length > 0) {
return stateAccounts[0].$newMessage();
}
}]
}
});
// if none of the above states are matched, use this as the fallback
@@ -131,8 +133,8 @@
*/
stateAccounts.$inject = ['$q', 'Account'];
function stateAccounts($q, Account) {
var accounts = Account.$findAll(mailAccounts);
var promises = [];
var accounts = Account.$findAll(mailAccounts),
promises = [];
// Fetch list of mailboxes for each account
angular.forEach(accounts, function(account, i) {
var mailboxes = account.$getMailboxes();
@@ -158,9 +160,10 @@
*/
stateMailbox.$inject = ['$stateParams', 'stateAccount', 'decodeUriFilter'];
function stateMailbox($stateParams, stateAccount, decodeUriFilter) {
var mailboxId = decodeUriFilter($stateParams.mailboxId);
var mailboxId = decodeUriFilter($stateParams.mailboxId),
_find;
// Recursive find function
var _find = function(mailboxes) {
_find = function(mailboxes) {
var mailbox = _.find(mailboxes, function(o) {
return o.path == mailboxId;
});
@@ -184,6 +187,14 @@
return stateMailbox.$filter();
}
/**
* @ngInject
*/
stateNewMessage.$inject = ['stateAccount'];
function stateNewMessage(stateAccount) {
return stateAccount.$newMessage();
}
/**
* @ngInject
*/
@@ -197,7 +208,7 @@
return message.$reload();
else
// Message not found
$state.go('mail.account.mailbox', { accountId: stateMailbox.$account.id, mailboxId: encodeUriFilter(stateMailbox.path) } );
$state.go('mail.account.mailbox', { accountId: stateMailbox.$account.id, mailboxId: encodeUriFilter(stateMailbox.path) });
}
/**

View File

@@ -197,27 +197,21 @@
* @returns a promise of the HTTP operations
*/
Account.prototype.$newMessage = function() {
var _this = this,
deferred = Account.$q.defer(),
message;
var _this = this;
// Query account for draft folder and draft UID
Account.$$resource.fetch(this.id.toString(), 'compose').then(function(data) {
return Account.$$resource.fetch(this.id.toString(), 'compose').then(function(data) {
Account.$log.debug('New message: ' + JSON.stringify(data, undefined, 2));
message = new Account.$Message(data.accountId, _this.$getMailboxByPath(data.mailboxPath), data);
var message = new Account.$Message(data.accountId, _this.$getMailboxByPath(data.mailboxPath), data);
return message;
}).then(function(message) {
// Fetch draft initial data
Account.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
return Account.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
Account.$log.debug('New message: ' + JSON.stringify(data, undefined, 2));
angular.extend(message.editable, data);
deferred.resolve(message);
}, function(data) {
deferred.reject(data);
return message;
});
}, function(data) {
deferred.reject(data);
});
return deferred.promise;
};
/**

View File

@@ -47,6 +47,7 @@
$$resource: new Resource(Settings.activeUser.folderURL + 'Mail', Settings.activeUser),
$Message: Message,
$$Acl: Acl,
selectedFolder: null,
PRELOAD: PRELOAD
});

View File

@@ -6,16 +6,62 @@
/**
* @ngInject
*/
MailboxController.$inject = ['$scope', '$rootScope', '$state', '$stateParams', 'stateAccount', 'stateMailbox', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
function MailboxController($scope, $rootScope, $state, $stateParams, stateAccount, stateMailbox, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox) {
$scope.account = stateAccount;
$rootScope.mailbox = stateMailbox;
$rootScope.currentFolder = stateMailbox;
$scope.selectMessage = function(message) {
$state.go('mail.account.mailbox.message', {accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path), messageId: message.uid});
};
MailboxController.$inject = ['$state', 'stateAccounts', 'stateAccount', 'stateMailbox', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
function MailboxController($state, stateAccounts, stateAccount, stateMailbox, encodeUriFilter, focus, Dialog, Account, Mailbox) {
var vm = this;
Mailbox.selectedFolder = stateMailbox;
vm.accounts = stateAccounts;
vm.account = stateAccount;
vm.selectedFolder = stateMailbox;
vm.selectMessage = selectMessage;
vm.unselectMessages = unselectMessages;
vm.confirmDeleteSelectedMessages = confirmDeleteSelectedMessages;
vm.copySelectedMessages = copySelectedMessages;
// vm.moveSelectedMessages = moveSelectedMessages;
function selectMessage(message) {
$state.go('mail.account.mailbox.message', {accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path), messageId: message.uid});
}
function unselectMessages() {
_.each(vm.selectedFolder.$messages, function(message) { message.selected = false; });
}
function confirmDeleteSelectedMessages() {
Dialog.confirm(l('Warning'),
l('Are you sure you want to delete the selected messages?'))
.then(function() {
// User confirmed the deletion
var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
vm.selectedFolder.$deleteMessages(selectedUIDs).then(function() {
vm.selectedFolder.$messages = _.difference(vm.selectedFolder.$messages, selectedMessages);
});
}, function(data, status) {
// Delete failed
});
}
function copySelectedMessages(folder) {
var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
vm.selectedFolder.$copyMessages(selectedUIDs, '/' + folder).then(function() {
// TODO: refresh target mailbox?
}, function(error) {
Dialog.alert(l('Error'), error.error);
});
}
// function moveSelectedMessages(folder) {
// var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected });
// var selectedUIDs = _.pluck(selectedMessages, 'uid');
// vm.selectedFolder.$moveMessages(selectedUIDs, '/' + folder).then(function() {
// // TODO: refresh target mailbox?
// vm.selectedFolder.$messages = _.difference(vm.selectedFolder.$messages, selectedMessages);
// });
// }
}
angular

View File

@@ -8,10 +8,31 @@
*/
MailboxesController.$inject = ['$scope', '$rootScope', '$stateParams', '$state', '$timeout', '$mdDialog', 'sgFocus', 'encodeUriFilter', 'Dialog', 'sgSettings', 'Account', 'Mailbox', 'User', 'stateAccounts'];
function MailboxesController($scope, $rootScope, $stateParams, $state, $timeout, $mdDialog, focus, encodeUriFilter, Dialog, Settings, Account, Mailbox, User, stateAccounts) {
$scope.activeUser = Settings.activeUser;
$scope.accounts = stateAccounts;
var vm = this,
account,
mailbox;
$scope.newFolder = function(parentFolder) {
vm.service = Mailbox;
vm.accounts = stateAccounts;
vm.newFolder = newFolder;
vm.delegate = delegate;
vm.editFolder = editFolder;
vm.revertEditing = revertEditing;
vm.selectFolder = selectFolder;
vm.saveFolder = saveFolder;
vm.exportMails = exportMails;
vm.confirmDelete = confirmDelete;
vm.share = share;
vm.iconForFolder = iconForFolder;
if ($state.current.name == 'mail' && vm.accounts.length > 0 && vm.accounts[0].$mailboxes.length > 0) {
// Redirect to first mailbox of first account if no mailbox is selected
account = vm.accounts[0];
mailbox = account.$mailboxes[0];
$state.go('mail.account.mailbox', { accountId: account.id, mailboxId: encodeUriFilter(mailbox.path) });
}
function newFolder(parentFolder) {
Dialog.prompt(l('New folder'),
l('Enter the new name of your folder :'))
.then(function(name) {
@@ -23,8 +44,9 @@
l(data.error));
});
});
};
$scope.delegate = function(account) {
}
function delegate(account) {
$mdDialog.show({
templateUrl: account.id + '/delegation', // UI/Templates/MailerUI/UIxMailUserDelegation.wox
controller: MailboxDelegationController,
@@ -56,7 +78,6 @@
vm.selectUser = selectUser;
function userFilter($query) {
//return User.$filter($query, folder.$acl.users);
return User.$filter($query, account.delegates);
}
@@ -70,7 +91,7 @@
vm.selectedUser = null;
}
}, function(data, status) {
Dialog.alert(l('Warning'), l('An error occured please try again.'))
Dialog.alert(l('Warning'), l('An error occured please try again.'));
});
}
@@ -92,48 +113,47 @@
}
}
}
};
$scope.editFolder = function(folder) {
$scope.editMode = folder.path;
} // delegate
function editFolder(folder) {
vm.editMode = folder.path;
focus('mailboxName_' + folder.path);
};
$scope.revertEditing = function(folder) {
}
function revertEditing(folder) {
folder.$reset();
$scope.editMode = false;
};
$scope.selectFolder = function(account, folder) {
if ($scope.editMode == folder.path)
vm.editMode = false;
}
function selectFolder(account, folder) {
if (vm.editMode == folder.path)
return;
$rootScope.currentFolder = folder;
$scope.editMode = false;
$rootScope.message = null;
vm.editMode = false;
$state.go('mail.account.mailbox', { accountId: account.id, mailboxId: encodeUriFilter(folder.path) });
};
$scope.saveFolder = function(folder) {
}
function saveFolder(folder) {
folder.$rename();
};
$scope.exportMails = function() {
window.location.href = ApplicationBaseURL + '/' + $rootScope.currentFolder.id + '/exportFolder';
};
$scope.confirmDelete = function(folder) {
if (folder.path != $scope.currentFolder.path) {
// Counter the possibility to click on the "hidden" secondary button
$scope.selectFolder(folder.$account, folder);
return;
}
}
function exportMails(folder) {
window.location.href = ApplicationBaseURL + '/' + folder.id + '/exportFolder';
}
function confirmDelete(folder) {
Dialog.confirm(l('Confirmation'), l('Do you really want to move this folder into the trash ?'))
.then(function() {
folder.$delete()
.then(function() {
$rootScope.currentFolder = null;
$state.go('mail');
}, function(data, status) {
Dialog.alert(l('An error occured while deleting the mailbox "%{0}".', folder.name),
l(data.error));
});
});
};
$scope.share = function(folder) {
}
function share(folder) {
//if (addressbook.id != vm.service.selectedFolder.id) {
// Counter the possibility to click on the "hidden" secondary button
//select(addressbook);
@@ -208,7 +228,7 @@
vm.selectedUser = null;
}
}, function(data, status) {
Dialog.alert(l('Warning'), l('An error occured please try again.'))
Dialog.alert(l('Warning'), l('An error occured please try again.'));
});
}
@@ -231,9 +251,9 @@
}
}
}
};
} // share
$scope.iconForFolder = function(folder) {
function iconForFolder(folder) {
if (folder.type == 'inbox')
return 'inbox';
else if (folder.type == 'draft')
@@ -247,51 +267,6 @@
// return 'folder_open';
return 'folder';
};
$scope.unselectMessages = function() {
_.each($rootScope.mailbox.$messages, function(message) { message.selected = false; });
};
$scope.confirmDeleteSelectedMessages = function() {
Dialog.confirm(l('Warning'),
l('Are you sure you want to delete the selected messages?'))
.then(function() {
// User confirmed the deletion
var selectedMessages = _.filter($rootScope.mailbox.$messages, function(message) { return message.selected });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
$rootScope.mailbox.$deleteMessages(selectedUIDs).then(function() {
$rootScope.mailbox.$messages = _.difference($rootScope.mailbox.$messages, selectedMessages);
});
}, function(data, status) {
// Delete failed
});
};
$scope.copySelectedMessages = function(folder) {
var selectedMessages = _.filter($rootScope.mailbox.$messages, function(message) { return message.selected });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
$rootScope.mailbox.$copyMessages(selectedUIDs, '/' + folder).then(function() {
// TODO: refresh target mailbox?
}, function(error) {
Dialog.alert(l('Error'), error.error);
});
};
// $scope.moveSelectedMessages = function(folder) {
// var selectedMessages = _.filter($rootScope.mailbox.$messages, function(message) { return message.selected });
// var selectedUIDs = _.pluck(selectedMessages, 'uid');
// $rootScope.mailbox.$moveMessages(selectedUIDs, '/' + folder).then(function() {
// // TODO: refresh target mailbox?
// $rootScope.mailbox.$messages = _.difference($rootScope.mailbox.$messages, selectedMessages);
// });
// };
if ($state.current.name == 'mail' && $scope.accounts.length > 0 && $scope.accounts[0].$mailboxes.length > 0) {
// Redirect to first mailbox of first account if no mailbox is selected
var account = $scope.accounts[0];
var mailbox = account.$mailboxes[0];
$state.go('mail.account.mailbox', { accountId: account.id, mailboxId: encodeUriFilter(mailbox.path) });
}
}

View File

@@ -105,8 +105,7 @@
if (oldUID != uid) {
this.uid = uid;
this.id = this.$absolutePath();
if (oldUID > -1) {
// For new messages, $mailbox doesn't exist
if (oldUID > -1 && this.$mailbox.uidsMap[oldUID]) {
this.$mailbox.uidsMap[uid] = this.$mailbox.uidsMap[oldUID];
this.$mailbox.uidsMap[oldUID] = null;
}
@@ -417,29 +416,21 @@
* @returns a promise of the HTTP operations
*/
Message.prototype.$newDraft = function(action) {
var _this = this,
deferred = Message.$q.defer(),
mailbox,
message;
var _this = this;
// Query server for draft folder and draft UID
Message.$$resource.fetch(this.id, action).then(function(data) {
return Message.$$resource.fetch(this.id, action).then(function(data) {
var mailbox, message;
Message.$log.debug('New ' + action + ': ' + JSON.stringify(data, undefined, 2));
mailbox = _this.$mailbox.$account.$getMailboxByPath(data.mailboxPath);
message = new Message(data.accountId, mailbox, data);
// Fetch draft initial data
Message.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
return Message.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
Message.$log.debug('New ' + action + ': ' + JSON.stringify(data, undefined, 2));
angular.extend(message.editable, data);
deferred.resolve(message);
}, function(data) {
deferred.reject(data);
return message;
});
}, function(data) {
deferred.reject(data);
});
return deferred.promise;
};
/**

View File

@@ -6,21 +6,39 @@
/**
* @ngInject
*/
MessageController.$inject = ['$scope', '$rootScope', '$stateParams', '$state', 'stateAccount', 'stateMailbox', 'stateMessage', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
function MessageController($scope, $rootScope, $stateParams, $state, stateAccount, stateMailbox, stateMessage, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox) {
$rootScope.message = stateMessage;
$scope.tags = {};
$scope.doDelete = function() {
MessageController.$inject = ['$scope', '$state', 'stateAccount', 'stateMailbox', 'stateMessage', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'Message'];
function MessageController($scope, $state, stateAccount, stateMailbox, stateMessage, encodeUriFilter, focus, Dialog, Account, Mailbox, Message) {
var vm = this;
vm.account = stateAccount;
vm.mailbox = stateMailbox;
vm.message = stateMessage;
vm.service = Message;
vm.tags = { searchText: '', selected: '' };
vm.doDelete = doDelete;
// Watch the message model "flags" attribute to remove on-the-fly a tag from the IMAP message
// when removed from the message viewer.
// TODO: this approach should be reviewed once md-chips supports ng-change.
$scope.$watchCollection('viewer.message.flags', function(oldTags, newTags) {
_.each(_.difference(newTags, oldTags), function(tag) {
vm.message.removeTag(tag);
});
});
function doDelete() {
stateMailbox.$deleteMessages([stateMessage.uid]).then(function() {
// Remove message from list of messages
stateMailbox.$messages = _.reject(stateMailbox.$messages, function(o) {
var index = _.findIndex(stateMailbox.$messages, function(o) {
return o.uid == stateMessage.uid;
});
if (index != -1)
stateMailbox.$messages.splice(index, 1);
// Remove message object from scope
$rootScope.message = null;
vm.message = null;
$state.go('mail.account.mailbox', { accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path) });
});
};
}
}
angular

View File

@@ -6,60 +6,18 @@
/**
* @ngInject
*/
MessageEditorController.$inject = ['$scope', '$rootScope', '$stateParams', '$state', '$q', 'FileUploader', 'stateAccounts', 'stateMessage', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'AddressBook'];
function MessageEditorController($scope, $rootScope, $stateParams, $state, $q, FileUploader, stateAccounts, stateMessage, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox, AddressBook) {
$scope.autocomplete = {to: {}, cc: {}, bcc: {}};
$scope.hideCc = true;
$scope.hideBcc = true;
if ($stateParams.actionName == 'reply') {
stateMessage.$reply().then(function(msgObject) {
console.debug("foo");
MessageEditorController.$inject = ['$stateParams', '$state', '$q', 'FileUploader', 'stateAccounts', 'stateMessage', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'AddressBook'];
function MessageEditorController($stateParams, $state, $q, FileUploader, stateAccounts, stateMessage, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox, AddressBook) {
var vm = this;
$scope.message = msgObject;
$scope.hideCc = (!msgObject.editable.cc || msgObject.editable.cc.length == 0);
$scope.hideBcc = (!msgObject.editable.bcc || msgObject.editable.bcc.length == 0);
});
}
else if ($stateParams.actionName == 'replyall') {
stateMessage.$replyAll().then(function(msgObject) {
$scope.message = msgObject;
$scope.hideCc = (!msgObject.editable.cc || msgObject.editable.cc.length == 0);
$scope.hideBcc = (!msgObject.editable.bcc || msgObject.editable.bcc.length == 0);
});
}
else if ($stateParams.actionName == 'forward') {
stateMessage.$forward().then(function(msgObject) {
$scope.message = msgObject;
$scope.hideCc = true;
$scope.hideBcc = true;
});
}
else if (angular.isDefined(stateMessage)) {
$scope.message = stateMessage;
}
$scope.identities = _.pluck(_.flatten(_.pluck(stateAccounts, 'identities')), 'full');
$scope.cancel = function() {
if ($scope.mailbox)
$state.go('mail.account.mailbox', { accountId: $scope.mailbox.$account.id, mailboxId: encodeUriFilter($scope.mailbox.path) });
else
$state.go('mail');
};
$scope.send = function(message) {
message.$send().then(function(data) {
$rootScope.message = null;
$state.go('mail');
}, function(data) {
console.debug('failure ' + JSON.stringify(data, undefined, 2));
});
};
$scope.userFilter = function($query) {
var deferred = $q.defer();
AddressBook.$filterAll($query).then(function(results) {
deferred.resolve(_.invoke(results, '$shortFormat', $query));
});
return deferred.promise;
};
$scope.uploader = new FileUploader({
vm.autocomplete = {to: {}, cc: {}, bcc: {}};
vm.hideCc = true;
vm.hideBcc = true;
vm.cancel = cancel;
vm.send = send;
vm.userFilter = userFilter;
vm.identities = _.pluck(_.flatten(_.pluck(stateAccounts, 'identities')), 'full');
vm.uploader = new FileUploader({
url: stateMessage.$absolutePath({asDraft: true}) + '/save',
autoUpload: true,
alias: 'attachments',
@@ -82,6 +40,53 @@
console.debug(item); console.debug('error = ' + JSON.stringify(response, undefined, 2));
}
});
if ($stateParams.actionName == 'reply') {
stateMessage.$reply().then(function(msgObject) {
vm.message = msgObject;
vm.hideCc = (!msgObject.editable.cc || msgObject.editable.cc.length == 0);
vm.hideBcc = (!msgObject.editable.bcc || msgObject.editable.bcc.length == 0);
});
}
else if ($stateParams.actionName == 'replyall') {
stateMessage.$replyAll().then(function(msgObject) {
vm.message = msgObject;
vm.hideCc = (!msgObject.editable.cc || msgObject.editable.cc.length == 0);
vm.hideBcc = (!msgObject.editable.bcc || msgObject.editable.bcc.length == 0);
});
}
else if ($stateParams.actionName == 'forward') {
stateMessage.$forward().then(function(msgObject) {
vm.message = msgObject;
});
}
else if (angular.isDefined(stateMessage)) {
vm.message = stateMessage;
}
function cancel() {
// TODO: delete draft?
if ($state.params.mailboxId)
$state.go('mail.account.mailbox', { accountId: $state.params.accountId, mailboxId: $state.params.mailboxId });
else
$state.go('mail');
}
function send() {
vm.message.$send().then(function(data) {
$state.go('mail');
}, function(data) {
console.debug('failure ' + JSON.stringify(data, undefined, 2));
});
}
function userFilter($query) {
var deferred = $q.defer();
AddressBook.$filterAll($query).then(function(results) {
deferred.resolve(_.invoke(results, '$shortFormat', $query));
});
return deferred.promise;
}
}
angular