Reputation: 7919
In my application I have a number of directives that modify various properties on a scope object using either their controller
or link
functions. When the application is in use by the user, the properties on this object will change. I want to make a deep copy of the object before any user changes are made so that I can restore its original state. For this it would be useful to have an event occur after all of the functions have run - ie, when Angular has finished bootstrapping.
My first thought was to create a custom directive that runs a function, and add it as the final element in the controller. However, it seems that Angular loads directives in a breadth-first fashion, so my "final" directive was one of the first to be linked.
Is there a way to do what I want?
Upvotes: 1
Views: 930
Reputation: 7919
I gave up on trying to find a post-link hook and instead tried to think about the problem in a different way.
The goal was to have directives inform an object that serves as a lookup for the 'default' values of various model properties. So for example, something like:
<my-directive ng-model="foo" default-value="bar"></my-directive>
Originally my directives looked something like this:
.directive("myDirective", function() {
return {
scope: { ngModel: '=', defaultValue: '@' },
link: function(scope, elem, attrs) {
$scope.ngModel = $scope.defaultValue;
// ...etc...
}
}
})
I realised that this could be done during the compile step as long as the default values weren't bindings. The solution I settled on looks something like this:
.service("defaultValues", function(someOtherDependency) {
this.aDefault = someOtherDependency.getDefault();
})
.directive("myDirective", function(defaultValues) {
return {
scope: { ngModel: '=' },
compile: function(elem, attrs) {
defaultValues[attrs.ngModel] = attrs.defaultValue;
}
// ...etc...
}
})
.controller("theController", function($scope, defaultValues) {
$scope.values = angular.copy(defaultValues);
})
The difference here is that I am injecting a service (a singleton) into my directive and setting a value on it at compile-time. This happens before the controller function is called, so the singleton is fully populated by the time it is.
I hope this helps someone else!
Upvotes: 0
Reputation: 26828
For what it's worth: There is an undocumented $$postDigest
function that was introduced with version 1.2. It allows you to add a function that is executed after a digest cycle. The function is executed only once.
So you could do something like
module.controller('myController', function($scope) {
$scope.$$postDigest(function() {
var copyOfScope = angular.copy($scope);
//...
});
But be aware of the fact that no matter what you try, it won't work as soon as anything happens asynchronously. That could be loading values or templates over HTTP or having some function executed with a timeout. So it may be impossible to achieve what you want.
Upvotes: 1