But, it's right there, so it can be implemented. However, I don't like using the $rootScope for this, what can be found in many examples on the net, in the same way I don't use globals, because they produce a mess. Here I'd like to propose an elegant solution for this.
I have the service that holds all controller states, and provide the initialization function that may be used when the state hasn't been cached yet. The code snippet:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
myModule.service('state', | |
function () { | |
/** The global/shared modules state (filled in modules.run) **/ | |
this.global = {}; | |
/** | |
* Initializes the scope state. If the scope state is already initialized and kept from previous invocation, | |
* the scope is initialized using the previous state. If the scope state doesn't exist, the scope is initialized | |
* using the initFunc. | |
* | |
* NOTE: that only objects are traced in the cached scope state. So it the scope contains primitives, they are | |
* not traced ie. the changes in the primitives on current scope are not reflected in cached version. | |
* | |
* @param scopeName {string} The virtual unique scope name (eg. 'ControllerName') | |
* @param $scope {object} Angular scope object that should be populated with the data | |
* @param initFunc {function} Scope initialization function(scope) - gets the cached scope in argument, not | |
* the real angular scope (!) | |
*/ | |
this.initScope = function (scopeName, $scope, initFunc) { | |
// initializes the cached scope if is not initialized yet | |
if (!angular.isDefined(this.global[scopeName])) { | |
console.debug('state:service', 'Creating new cached scope:', scopeName); | |
var cachedScope = {}; | |
initFunc(cachedScope); | |
this.global[scopeName] = cachedScope; | |
} else | |
console.debug('state:service', 'Using existing cached scope:', scopeName); | |
// populates the cached scope to current scope | |
angular.forEach(this.global[scopeName], function (propVal, propName) { | |
$scope[propName] = propVal; | |
}); | |
}; | |
/** | |
* Deletes the cached version of scope. After next initScope() the scope will be populated with | |
* initFunc data again. | |
* @param scopeName {string} The virtual unique scope name (eg. 'ControllerName') | |
*/ | |
this.deleteScope = function (scopeName) { | |
if (angular.isDefined(this.global[scopeName])) { | |
console.debug('state:service', 'Deleting existing cached scope:', scopeName); | |
delete this.global[scopeName]; | |
} | |
}; | |
}); | |
myModule.controller('myCtrl', | |
['$scope', 'state', | |
function($scope, state) { | |
// init the scope or use cached version of data | |
state.initScope('myCtrl', $scope, function(scope) { | |
scope.moduleState = { | |
detailsVisible: false // if the details are visible | |
}; | |
}); | |
}]); |