Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@RadoMark
Last active December 26, 2019 19:14
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save RadoMark/fbd501b26e0c389c4135 to your computer and use it in GitHub Desktop.
Save RadoMark/fbd501b26e0c389c4135 to your computer and use it in GitHub Desktop.
Watchers toggler directive
<div ng-app>
<div ng-controller="TestCtrl">
<ul ng-repeat="elements in array" watchers-toggler="toggler()">
<li ng-repeat="element in elements">{{element}}</li>
</ul>
</div>
</div>
function TestCtrl($scope, $timeout) {
$scope.array = [];
for(var i = 0; i < 10; i++) {
$scope.array[i] = [];
for(var j = 0; j < 10; j++) {
$scope.array[i].push(j);
}
}
$scope.tog = false;
$scope.toggler = function() { return $scope.tog };
// manipulate the $scope.tog variable and check number of watchers
}
module
.directive('watchersToggler', ['$parse', '$timeout', function($parse, $timeout) {
return {
restrict: 'EA',
scope: {
toggler: '&watchersToggler',
refreshSuspensionOn: '=refreshHideOn'
},
link: function($scope, element, attrs) {
var watchers = {
suspended: false
};
$scope.$watch(function() { return $scope.toggler() }, function(newToggler, oldToggler) {
if(typeof newToggler == 'boolean') {
if(newToggler) {
//element.hide(); - with jquery dependency
element.css('display', 'none');
suspendFromRoot();
} else {
//element.show(); - with jquery dependency
element.css('display', 'block');
resumeFromRoot();
}
}
});
$scope.$watch('refreshSuspensionOn', function(newVal, oldVal) {
if(newVal !== oldVal) refreshSuspensionFromRoot()
}, true);
function suspendFromRoot() {
if(!watchers.suspended) {
$timeout(function() {
suspendWatchers();
watchers.suspended = true;
})
}
}
function refreshSuspensionFromRoot() {
if(watchers.suspended) {
$timeout(function() {
suspendWatchers();
})
}
}
function resumeFromRoot() {
if(watchers.suspended) {
$timeout(function() {
resumeWatchers();
watchers.suspended = false;
})
}
}
function suspendWatchers() {
iterateSiblings($scope, suspendScopeWatchers);
iterateChildren($scope, suspendScopeWatchers);
};
function resumeWatchers() {
iterateSiblings($scope, resumeScopeWatchers);
iterateChildren($scope, resumeScopeWatchers);
};
var mockScopeWatch = function(scopeId) {
return function(watchExp, listener, objectEquality, prettyPrintExpression) {
watchers[scopeId].unshift({
fn: angular.isFunction(listener) ? listener : angular.noop,
last: void 0,
get: $parse(watchExp),
exp: prettyPrintExpression || watchExp,
eq: !!objectEquality
})
}
}
function suspendScopeWatchers(scope) {
if(!watchers[scope.$id]) {
watchers[scope.$id] = scope.$$watchers || [];
scope.$$watchers = [];
scope.$watch = mockScopeWatch(scope.$id)
}
}
function resumeScopeWatchers(scope) {
if(watchers[scope.$id]) {
scope.$$watchers = watchers[scope.$id];
if(scope.hasOwnProperty('$watch')) delete scope.$watch;
watchers[scope.$id] = false
}
}
function iterateSiblings(scope, operationOnScope) {
while (!!(scope = scope.$$nextSibling)) {
operationOnScope(scope);
iterateChildren(scope, operationOnScope);
}
}
function iterateChildren(scope, operationOnScope) {
while (!!(scope = scope.$$childHead)) {
operationOnScope(scope);
iterateSiblings(scope, operationOnScope);
}
}
}
}
}]);
@Ashok-vinfotech
Copy link

I am using this directive but it's giving error for $compile:multidir Multiple Directive Resource Contention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment