Below a small example of what I want to simplify. I have the same structure set up for a few other models, and was wondering if I could prevent typing out the same functionality but with just different messages/model.
Is it possible to reuse a controller & pass parameters? (In this case, the name of the model + the messages that need to be shown...). Ideally, I just want the basic CRUD controller to be reused, but allow custom methods, just in case.
angular.module('employees.controllers', ["templates.app", "ui.bootstrap"])
.controller("EmployeeListController", ["$scope", "$modal", "Restangular", function ($scope, $modal, Restangular) {
var Employee = Restangular.all("employees");
Employee.getList().then(function (employees) {
$scope.employees = employees;
})
$scope.createEmployee = function () {
$modal.open({
templateUrl: 'employees/partials/employees.manage.modal.tpl.html',
controller: 'EmployeeCreateController'
}).result.then(function (employee) {
Employee.post(employee).then(function (newEmployee) {
$scope.messageService.addMessage("success", "Employee was successfully created!");
$scope.employees.push(newEmployee);
});
});
};
$scope.deleteEmployee = function (employee) {
employee.remove().then(function () {
$scope.messageService.addMessage("success", "Employee was successfully deleted!");
$scope.employees = _.without($scope.employees, employee);
});
};
$scope.editEmployee = function (originalEmployee) {
$modal.open({
templateUrl: 'employees/partials/employees.manage.modal.tpl.html',
controller: 'EmployeeUpdateController',
resolve: {
employee: function () {
return Restangular.copy(originalEmployee);
}
}
}).result.then(function (employee) {
employee.put().then(function (updated_employee) {
$scope.messageService.addMessage("success", "Employee was successfully updated!");
var originalIndex = _.indexOf($scope.employees, originalEmployee);
$scope.employees[originalIndex] = updated_employee;
});
});
};
}]).controller("EmployeeCreateController", ["$scope", "$modalInstance", "$timeout", function ($scope, $modalInstance, $timeout) {
$scope.createMode = true;
$scope.form = {};
$scope.employee = {};
$scope.datepicker = {};
$scope.ok = function () {
if ($scope.form.createResource.$valid) {
$modalInstance.close($scope.employee);
}
};
$scope.open = function () {
$timeout(function () {
$scope.datepicker.opened = true;
});
};
$scope.cancel = function () {
$modalInstance.dismiss("cancel");
};
}]).controller("EmployeeUpdateController", ["$scope", "$modalInstance", "employee", function ($scope, $modalInstance, employee) {
$scope.createMode = false;
$scope.form = {};
$scope.employee = employee;
$scope.ok = function () {
if ($scope.form.createResource.$valid) {
$modalInstance.close($scope.employee);
}
};
$scope.cancel = function () {
$modalInstance.dismiss("cancel");
};
}]);
Related
I have an AngularJS module with code that calls a modal popup. I also have code that calls an MVC Web API controller method. Both of these functions work independently of one another right now. What I would like to happen is after the user clicks the OK button on the modal, I want to get the value of the modal text box and send it to the API controller as a parameter. The code I have so far is below:
app.js:
(function () {
'use strict';
var app = angular.module("CRNApp", ['ui.bootstrap','trNgGrid']);
var MainController = function ($scope, $http, $log, $uibModal) {
$scope.showGrid = false;
$scope.showPolicyScreen = false;
$scope.CRNViewModel = {
policyId: 0
};
$scope.openPolicyId = function () {
$uibModal.open({
templateUrl: 'templates/popupGetPolicy.cshtml',
backdrop: false,
windowClass: 'modal',
controller: function ($scope, $uibModalInstance, $log, CRNViewModel) {
$scope.CRNViewModel = CRNViewModel;
$scope.submit = function () {
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
resolve: { CRNViewModel: function () { return $scope.CRNViewModel; } }
});//end of modal.open
}; // end of scope.open fu
$scope.policyLookup = function (policyNumber) {
$scope.loading = true;
$scope.CRNViewModel.policyId = policyNumber; //"WCZ25999"
$http.post("/api/Policy"
, $scope.CRNViewModel
, { header: { 'Content-Type': 'application/json' } })
.then(function (response) {
$scope.policy = response.data;
$scope.loading = false;
$scope.showGrid = false;
$scope.showPolicyScreen = true;
})
.catch(function (error) {
console.log(error);
$scope.loading = false;
$scope.showGrid = false;
});
};
};
app.controller("MainController", MainController);
}());
The MVC API Controller method:
// POST: api/Policy
public IHttpActionResult Post([FromBody]CRNViewModel policy)
{
CRNViewModel _crnVM = new CRNViewModel();
IConditionalRenewalNotices _crn = new ConditionalRenewalNoticesRepository();
_crnVM = _crn.GetPolicyByPolicyId(policy.PolicyId);
return Json(_crnVM);
}
Return the textbox value when you close the $uibModalInstance instance and then add a callback for the modal result:
var modal = $uibModal.open({
templateUrl: 'templates/popupGetPolicy.cshtml',
backdrop: false,
windowClass: 'modal',
controller: function($scope, $uibModalInstance, $log, CRNViewModel) {
$scope.CRNViewModel = CRNViewModel;
$scope.submit = function () {
// pass in the value you want to return
$uibModalInstance.close('WCZ25999');
}
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
},
resolve: { CRNViewModel: function() { return $scope.CRNViewModel; } }
});
modal.result.then(function (value) {
$scope.policyLookup(value);
});
Im trying to add another function to my controller but it keeps breaking the controller.
here is my code:
.controller('ClimbController', [
'$scope', '$stateParams', 'Climbs', function(
$scope, $stateParams, Climbs) {
var climb_id = $stateParams.climbId;
var areaId = $stateParams.areaId;
if (!isNaN(climb_id)) {
climb_id = parseInt(climb_id);
}
if (!isNaN(areaId)) {
areaId = parseInt(areaId);
}
$scope.selected_ = {};
$scope.items = [];
$scope.details = true;
// looping though all data and get particular product
$scope.selectClimb = function(areas){
areas.forEach(function(data) {
if(data._id == climb_id){
$scope.selected_ = data;
}
});
}
// get all posts // try some function to get a single produt from server
$scope.getPosts = function(){
Climbs.getPosts()
.success(function (data) {
// data = feed.json file
var climbs = [];
data.areas.map(function(area) {
if (area._id === areaId) {
climbs = area.climbs;
}
});
$scope.selectClimb(climbs);
})
.error(function (error) {
$scope.items = [];
});
}
$scope.getPosts();
}
])
And I ned to add this to it:
.controller('MyCtrl', function($scope, $ionicModal) {
$ionicModal.fromTemplateUrl('test-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
});
When I try to add this to the code it breaks it. I nee to either add it as another function or whatever is needed to add it to the code.
Thanks so much
Assuming that you want to merge 'MyCtrl functions into ClimbController then
.controller('ClimbController', ['$scope', '$stateParams', 'Climbs','$ionicModal', function($scope, $stateParams, Climbs,$ionicModal) {
var climb_id = $stateParams.climbId;
var areaId = $stateParams.areaId;
if (!isNaN(climb_id)) {
climb_id = parseInt(climb_id);
}
if (!isNaN(areaId)) {
areaId = parseInt(areaId);
}
$scope.selected_ = {};
$scope.items = [];
$scope.details = true;
// looping though all data and get particular product
$scope.selectClimb = function(areas){
areas.forEach(function(data) {
if(data._id == climb_id){
$scope.selected_ = data;
}
});
}
// get all posts // try some function to get a single produt from server
$scope.getPosts = function(){
Climbs.getPosts()
.success(function (data) {
// data = feed.json file
var climbs = [];
data.areas.map(function(area) {
if (area._id === areaId) {
climbs = area.climbs;
}
});
$scope.selectClimb(climbs);
})
.error(function (error) {
$scope.items = [];
});
}
$scope.getPosts();
$ionicModal.fromTemplateUrl('test-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
}])
I have an app which fetches data from a database on load.
Since the data in the database changes every few seconds, I would like to dynamically add the new data in the database into the table in the HTML page.
Any ideas on how to implement without reloading the controller?
The current code:
app.js
var app = angular.module('myApp', ['ui.bootstrap','countTo']);
app.filter('startFrom', function() {
return function(input, start) {
if(input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.config(['$compileProvider', function($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|http?|file|data):/);
}]);
app.controller('customersCrtl', function ($scope, $http, $timeout) {
$scope.$emit('LOAD');
$scope.progressBar = { progress : 0 };
$http.get('ajax/getCustomers.php').success(function(data){
$scope.list = data;
$scope.currentPage = 1; //current page
$scope.entryLimit = 50; //max no of items to display in a page
$scope.filteredItems = $scope.list.length; //Initially for no filter
$scope.totalItems = $scope.list.length;
$scope.$emit('UNLOAD');
});
(function progress(){
if($scope.progressBar.progress < 100){
$timeout(function(){
$scope.progressBar.progress += 1;
progress();
},5);
}
})();
$scope.setPage = function(pageNo) {
$scope.currentPage = pageNo;
};
$scope.filter = function() {
$timeout(function() {
$scope.filteredItems = $scope.filtered.length;
}, 10);
};
$scope.sort_by = function(predicate) {
$scope.predicate = predicate;
$scope.reverse = !$scope.reverse;
};
});
app.controller('delayController',['$scope',function($scope){
$scope.$on('LOAD',function(){$scope.loading=true});
$scope.$on('UNLOAD',function(){$scope.loading=false});
}]);
app.controller("PostsCtrl", function($scope, $http, $timeout) {
$scope.progressBarScanned = { progressScanned : 0 };
(function tick() {
$http.get('ajax/scanStatus.php').
then(function(response) {
$scope.posts = response.data;
$scope.scanProgerss = $scope.posts[0].isScanning;
$scope.scanPercentage = $scope.posts[0].scanPercentage;
$scope.timeToFinish = $scope.posts[0].timeToFinish;
$scope.amountScanned = $scope.posts[0].amountScanned;
$scope.totalItemsToScan = $scope.posts[0].totalItemsToScan;
$scope.avgScanTimePerItem = $scope.posts[0].avgScanTimePerItem;
});
$timeout(tick, 1000);
})();
(function progressScanned(scanned){
if($scope.scanPercentage < 100){
$timeout(function(){
$scope.progressScanned.progress = 1;
progressScanned();
},5);
}
})();
});
//Modal
var ModalDemoCtrl = function ($scope, $modal) {
$scope.open = function (imageKey) {
$modal.open({
templateUrl: 'myModalContent.html',
backdrop: true,
windowClass: 'full',
controller: function ($scope, $modalInstance, data, imageKey) {
$scope.data='';
$scope.data = data;
$scope.getImage = function () {
return $scope.data[imageKey];
}
$scope.cancel = function () {
$modalInstance.dismiss('close');
};
},
resolve: {
data: function() {
// access outer controller scope by using $scope.$parent
return $scope.$parent.data;
},
imageKey: function() {
return imageKey;
}
}
});
}};
I'm trying to use a modal dialog as a selection list. I've got the modal dialog configured as a factory.
How can I get the code at http://plnkr.co/edit/fVpNtrr4Ez68yWYUlgnO?p=preview to return the selected person from the modal window?
var selectModal = function ($modal) {
function show(personList) {
var modalOptions = {
templateUrl: "select-modal.html",
controller: selectModalInstanceCtrl,
controllerAs: "modal",
windowClass: "ab-modal-window",
resolve: {
personList: function () { return personList; }
}
};
var modalInstance = $modal.open(modalOptions);
modalInstance.result.then(function (person) {
return person;
});
}
return {
show: show
};
};
var selectModalInstanceCtrl = function ($modalInstance, personList) {
var modalVm = this;
modalVm.personList = personList;
modalVm.selectPerson = function (person) {
$modalInstance.close(person);
};
modalVm.ok = function () {
$modalInstance.dismiss("ok");
};
};
var mainCtrl = function (selectModal)
{
var vm = this;
vm.personList = ['Tom','Dick','Harry','Jane'];
vm.selectedPerson = null;
vm.showSelectModal = function () {
vm.selectedPerson = selectModal.show(vm.personList, vm.selectedPerson);
};
};
selectModalInstanceCtrl.$inject = ["$modalInstance", "personList"];
selectModal.$inject = ['$modal'];
mainCtrl.$inject = ['selectModal'];
angular.module('app', ['ui.bootstrap']);
angular.module('app').factory('selectModal', selectModal);
angular.module('app').controller('mainCtrl', mainCtrl);
At line 18 in script.js, the selected person is there but I can't get it passed back to the main controller.
// Code goes here
var selectModal = function ($modal) {
function show(personList) {
var modalOptions = {
templateUrl: "select-modal.html",
controller: selectModalInstanceCtrl,
controllerAs: "modal",
windowClass: "ab-modal-window",
resolve: {
personList: function () { return personList; }
}
};
var modalInstance = $modal.open(modalOptions);
return modalInstance;
}
return {
show: show
};
};
var selectModalInstanceCtrl = function ($modalInstance, personList) {
var modalVm = this;
modalVm.personList = personList;
modalVm.selectPerson = function (person) {
$modalInstance.close(person);
};
modalVm.ok = function () {
$modalInstance.dismiss("ok");
};
};
var mainCtrl = function (selectModal)
{
var vm = this;
vm.personList = ['Tom','Dick','Harry','Jane'];
vm.selectedPerson = null;
vm.showSelectModal = function () {
var modalInstance = selectModal.show(vm.personList);
modalInstance.result.then(function (person) {
vm.selectedPerson = person;
});
};
};
selectModalInstanceCtrl.$inject = ["$modalInstance", "personList"];
selectModal.$inject = ['$modal'];
mainCtrl.$inject = ['selectModal'];
angular.module('app', ['ui.bootstrap']);
angular.module('app').factory('selectModal', selectModal);
angular.module('app').controller('mainCtrl', mainCtrl);
Say I have following controllers:
controller("MyCtrl1", ["$scope", "$sce", "myService", "$location",
function ($scope, $sce, myService, $location) {
$scope.Resources = window.MyGlobalResorcesObject;
$scope.trustedHtml = function (input) {
return $sce.trustAsHtml(input);
};
$scope.startProcessing = function () {
$scope.processingRequest = true;
};
$scope.endProcessing = function () {
$scope.processingRequest = false;
$scope.$apply();
};
//some MyCtrl1-specific code goes here
}]).
controller("MyCtrl2", ["$scope", "$sce", "myService", "$location",
function ($scope, $sce, myService, $location) {
$scope.Resources = window.MyGlobalResorcesObject;
$scope.trustedHtml = function (input) {
return $sce.trustAsHtml(input);
};
$scope.startProcessing = function () {
$scope.processingRequest = true;
};
$scope.endProcessing = function () {
$scope.processingRequest = false;
$scope.$apply();
};
//some MyCtrl2-specific code goes here
}]);
You see, code is duplicated.I want to reuse common code.
What is the common practice to achieve this?
Use a common service:
module.factory('processing', function($sce) {
function initialize($scope) {
$scope.Resources = window.MyGlobalResorcesObject;
$scope.trustedHtml = function(input) {
return $sce.trustAsHtml(input);
};
$scope.startProcessing = function() {
$scope.processingRequest = true;
};
$scope.endProcessing = function () {
$scope.processingRequest = false;
$scope.$apply();
};
}
return {
initialize: initialize;
}
});
And then in your controllers:
controller("MyCtrl1", function($scope, processing) {
processing.initialize($scope);
}