i'm trying to display a Bootstrap modal Dialog when a Variable in a Service is changed.
I'm currently doing this with broadcast. I'm new to angular so any help to improve my code is appreciated.
This Code works but i wanted to know if this is the correct way to do this.
My Service:
utils.service('UtilsService', function ($rootScope) {
this.objectToDelete = "";
this.deleteMessage = "";
this.DeleteObject = function (object, message) {
this.objectToDelete = object;
this.deleteMessage = message;
$rootScope.$broadcast('objectChanged', this.objectToDelete);
}
});
My Directive:
verwaltungApp.directive('deletedialog', ['UtilsService', function (UtilsService) {
return {
restrict: 'E',
controller: function ($scope, $attrs, UtilsService) {
$scope.$on("objectChanged", function (event, args) {
if (UtilsService.objectToDelete) {
$scope.ObjectToDelete = UtilsService.objectToDelete;
$scope.Message = UtilsService.deleteMessage;
$('#modalErrorDialog').modal('show');
}
});
$scope.DeleteObject = function () {
$scope.ObjectToDelete.Delete();
$scope.ObjectToDelete = null;
$('#modalErrorDialog').modal('hide');
}
$scope.Cancel = function () {
$scope.ObjectToDelete = null;
$('#modalErrorDialog').modal('hide');
}
},
templateUrl: '/shared/DeleteDialog'
};
}]);
I tried it with $watch before but that did not work for me.
The main thing i want to do is to place this directive on my Layout Page so i can call it from any controller with an object i want to delete.
Related
i was trying a sample pagination for that i have created an directive like this(am not sure its correct)
(function() {
app.directive("myPagination", function() {
return {
restrict: 'E',
templateUrl: 'pag.html'
};
});
})();
and my pag.html is
<ul class="pagination" ng-controller="PagingController">
<li ng-repeat="x in pageing" ng-click="change(x.pageno)">{{x.pageno}}</li>
</ul>
and my PageingController is like this
app.controller('PagingController', function($scope) {
$scope.$on('pageinfo', function(event, args) {
$scope.numbtn = args.numbtn;
$scope.totaldata = args.totaldata;
$scope.selet = args.selet;
$scope.starter();
})
$scope.starter = function() {
$scope.pageing = [];
let i;
for (i = 0; i < $scope.numbtn; i++) {
$scope.pageing[i] = i;
}
console.log($scope.pageing);
}
$scope.change = function(btnclk) {
alert(btnclk);
}
});
and <my-pagination></my-pagination> this is how i tried in index page. but the problem is its not showing anything even no errors can any one correct this please
Add the PageingController controller to directive instead of the template
(function() {
app.directive("myPagination", function() {
return {
restrict: 'E',
templateUrl: 'pag.html',
controller : 'PagingController'
};
});
})()
Demo
Make sure subscriber event $on is executing. otherwise page array is empty
I've been doing a todo list with AngularJS and want to know if there's a way to focus on a input box after creating it by clicking on a button.
Actually, my save function inside the controller is defined like this:
$scope.save = function() {
$scope.objetivo.$save()
.then(function() {
$scope.message = {
text : 'Saved'
};
$scope.objective = new Objective();
})
.catch(function(err) {
console.log(err.data);
if(err.data.code === 11000) {
text = 'This objective is already registered'
}
$scope.message = {
text : text || "Error when saving"
};
});
};
I think there's might be a way by adding the input box and then focusing on it, but I don't know how to do it.
This fiddle shows you how to implement focus elements even on async logics.
View
<div ng-controller="MyCtrl">
<button ng-click="someAsyncFunction()">
Set focus on async functions
</button>
<input type="text"
set-focus="{{setFocus}}">
</div>
AngularJS Application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope, $timeout) {
$scope.someAsyncFunction = function ()
//the following timeout indicates ansyc functions.
$timeout(function () {
$scope.setFocus = true;
}, 250);
}
});
myApp.directive('setFocus', function($timeout) {
return {
scope: { trigger: '#setFocus' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
},250);
}
});
}
};
});
I'm writing an AngularJS application and I'm searching for a way to unit test every single aspect.
In this particular case, I need to unit test a custom directive which I've written that represents a control.
The directive can be found here:
var officeButton = angular.module('OfficeButton', []);
officeButton.directive('officeButton', function() {
return {
restrict: 'E',
replace: false,
scope: {
isDefault: '#',
isDisabled: '#',
control: '=',
label: '#'
},
template: '<div class="button-wrapper" data-ng-click="onClick()">' +
'<a href="#" class="button normal-button">' +
'<span>{{label}}</span>' +
'</a>' +
'</div>',
controller: ['$scope', function($scope) {
var event = this;
var api = {
changeLabel: function(label) {
$scope.label = label;
},
enable: function() {
$scope.isDisabled = false;
},
disable: function() {
$scope.isDisabled = true;
},
setAsDefault: function() {
$scope.isDefault = true;
},
removeDefault: function() {
$scope.isDefault = false;
}
};
event.onClick = function() {
if (typeof $scope.control.onClick === 'function') { $scope.control.onClick(); }
};
$.extend($scope.control, api);
function Init() {
if ($scope.isDefault === 'true') { $scope.isDefault = true; }
else { $scope.isDefault = false; }
}
Init();
}],
link: function(scope, element, attributes, controller) {
scope.$watch('isDefault', function(value) {
if (value === 'true' || value) { $('a', element).addClass('button-default'); }
else { $('a', element).removeClass('button-default'); }
});
scope.onClick = function() { controller.onClick(); }
}
}
});
This directive can be called by using the following HTML snippet:
<office-button label="Office Web Controls" control="buttonController"></office-button>
Now, this directive exposes an API which functions such as changeLabel, enable, disable, ....
Now, those functions are not defined on the load of the application, meaning if at the bottom of my HTML I call the following code:
$scope.buttonController.changeLabel('Office Web Controls for Web Applications Directive Demo');
It will throw an error because the changeLabel() method is not defined.
In order to make it function, I need to wrap those calls in an angular.ready function, such as:
angular.element(document).ready(function () {
$scope.buttonController.changeLabel('Office Web Controls for Web Applications Directive Demo');
});
Here's a plunker for your information.
Now, I'm writing unit tests using Jasmine, and here's what I have for the moment:
describe('Office Web Controls for Web Applications - Button Testing.', function() {
// Provides all the required variables to perform Unit Testing against the 'button' directive.
var $scope, element;
var buttonController = {};
// Loads the directive 'OfficeButton' before every test is being executed.
beforeEach(module('OfficeButton'));
// Build the element so that it can be called.
beforeEach(inject(function($rootScope, $compile) {
// Sets the $scope variable so that it can be used in the future.
$scope = $rootScope;
$scope.control = buttonController;
element = angular.element('<office-button control="buttonController"></office-button>');
$compile(element)($scope);
$scope.$digest();
}));
it('Should expose an API with certain functions.', function() {
});
});
Now, in the it function, I would like to test if the $scope.control does expose the API as defined in the directive.
The problem is that the page needs to be ready before the API is available.
Any tought on how to change the code or how to unit test this correctly?
I've found the issue, it was just a wrong configuration on the unit test.
When using this code:
$scope.control = buttonController;
element = angular.element('<office-button control="buttonController"></office-button>');
I must change the element to:
$scope.control = buttonController;
element = angular.element('<office-button control="control"></office-button>');
I have two controllers.
There are functions that are identical and others that are differ.
For example:
Controller 1:
app.controller('ControllerOne', ['$scope','HelperService',
function ($scope, HelperService) {
$scope.helperService = HelperService; //get an instance of the HelperService
$scope.select = function () {
$scope.helperService.doA();
$scope.helperService.doB();
$scope.helperService.doC();
};
$scope.filter = function () {
$scope.helperService.doB();
$scope.helperService.doC();
$scope.helperService.doE();
$scope.helperService.doF();
};
}
]);
The second controller:
app.controller('ControllerOne', ['$scope','HelperService',
function ($scope, HelperService) {
$scope.helperService = HelperService; //get an instance of the HelperService
$scope.select = function () {
$scope.helperService.doA();
$scope.helperService.doB();
$scope.helperService.doC();
$scope.helperService.doD();
};
$scope.filter = function () {
$scope.helperService.doB();
$scope.helperService.doC();
$scope.helperService.doD();
$scope.helperService.doF();
};
}
]);
I have partials html to use the same click event but it depends on the controller:
<div ng-click="select()"></div>
How can I avoid from duplicated code on both controllers?
Here is the directive:
directive('cgHasPermissions', ['$animate', '$rootScope', 'PermissionService', 'PERMISSION', '$compile', function ($animate, $rootScope, PermissionService, PERMISSION, $compile) {
return {
multiElement: true,
transclude: 'element',
restrict: 'A',
$$tlb: true,
link: function ($scope, $element, $attr, ctrl, $transclude) {
var block, childScope, previousElements;
var unregister = $scope.$watch('user', function (newValue, oldValue) {
var value = $attr.cgHasPermissions;
var needsPermissions = value || ""
if($rootScope.user && $rootScope.permissions) {
unregister()
}
needsPermissions = value.replace(/\s+/g,"").split(",");
needsPermissions = _.map(needsPermissions, function(perm){
return PERMISSION[perm];
})
var user = $rootScope.user;
if(!needsPermissions || PermissionService.hasPermissions(needsPermissions)){
if (!childScope) {
$transclude (function (clone, newScope) {
childScope = newScope;
clone [clone.length++] = document.createComment (' end cgHasPermissions: ' + $attr.cgHasPermissions + ' ');
block = {
clone: clone
}
$animate.enter(clone, $element.parent (), $element);
});
}
} else {
if (previousElements) {
previousElements.remove();
previousElements = null;
}
if (childScope) {
childScope.$destroy();
childScope = null;
}
if (block) {
previousElements = getBlockNodes (block.clone);
$animate.leave (previousElements).then(function () {
previousElements = null;
});
block = null;
}
}
})
}
};
}])
Here is the HTML
<a ui-sref="addStudentForm" cg-has-permissions="canAddNewStudent,canViewStudent">+</a>
There is no problem in the logic of how the permissions work. I have verified that. whenever I remove the directive form HTML, ui-sref works just fine but when I add my directive, the ui-sref probably doesn't get executed and href attributed is not added at all.
I tried an ng-click, which also doesn't work.
What is in this directive that is not letting other directives get executed ?
What I have done is, take the source code of ng-if and create my own directive with an extra condition of permission check but ng-if does work with other elements what's wrong here ?