When I load a view, I'd like to run some initialization code in its associated controller.
To do so, I've used the ng-init directive on the main element of my view:
<div ng-init="init()">
blah
</div>
and in the controller:
$scope.init = function () {
if ($routeParams.Id) {
//get an existing object
});
} else {
//create a new object
}
$scope.isSaving = false;
}
First question: is this the right way to do it?
Next thing, I have a problem with the sequence of events taking place. In the view I have a 'save' button, which uses the ng-disabled
directive as such:
<button ng-click="save()" ng-disabled="isClean()">Save</button>
the isClean()
function is defined in the controller:
$scope.isClean = function () {
return $scope.hasChanges() && !$scope.isSaving;
}
As you can see, it uses the $scope.isSaving
flag, which was initialized in the init()
function.
PROBLEM: when the view is loaded, the isClean function is called before the init()
function, hence the flag isSaving
is undefined
. What can I do to prevent that?
This question is related to
angularjs
Or you can just initialize inline in the controller. If you use an init function internal to the controller, it doesn't need to be defined in the scope. In fact, it can be self executing:
function MyCtrl($scope) {
$scope.isSaving = false;
(function() { // init
if (true) { // $routeParams.Id) {
//get an existing object
} else {
//create a new object
}
})()
$scope.isClean = function () {
return $scope.hasChanges() && !$scope.isSaving;
}
$scope.hasChanges = function() { return false }
}
I use the following template in my projects:
angular.module("AppName.moduleName", [])
/**
* @ngdoc controller
* @name AppName.moduleName:ControllerNameController
* @description Describe what the controller is responsible for.
**/
.controller("ControllerNameController", function (dependencies) {
/* type */ $scope.modelName = null;
/* type */ $scope.modelName.modelProperty1 = null;
/* type */ $scope.modelName.modelPropertyX = null;
/* type */ var privateVariable1 = null;
/* type */ var privateVariableX = null;
(function init() {
// load data, init scope, etc.
})();
$scope.modelName.publicFunction1 = function () /* -> type */ {
// ...
};
$scope.modelName.publicFunctionX = function () /* -> type */ {
// ...
};
function privateFunction1() /* -> type */ {
// ...
}
function privateFunctionX() /* -> type */ {
// ...
}
});
Since AngularJS 1.5 we should use $onInit
which is available on any AngularJS component. Taken from the component lifecycle documentation since v1.5 its the preffered way:
$onInit() - Called on each controller after all the controllers on an element have been constructed and had their bindings initialized (and before the pre & post linking functions for the directives on this element). This is a good place to put initialization code for your controller.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
//default state
$scope.name = '';
//all your init controller goodness in here
this.$onInit = function () {
$scope.name = 'Superhero';
}
});
The component lifecycle gives us the ability to handle component stuff in a good way. It allows us to create events for e.g. "init", "change" or "destroy" of an component. In that way we are able to manage stuff which is depending on the lifecycle of an component. This little example shows to register & unregister an $rootScope
event listener $on
. By knowing, that an event $on
binded on $rootScope
will not be undinded when the controller loses its reference in the view or getting destroyed we need to destroy a $rootScope.$on
listener manually. A good place to put that stuff is $onDestroy
lifecycle function of an component:
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope, $rootScope) {
var registerScope = null;
this.$onInit = function () {
//register rootScope event
registerScope = $rootScope.$on('someEvent', function(event) {
console.log("fired");
});
}
this.$onDestroy = function () {
//unregister rootScope event by calling the return function
registerScope();
}
});
Source: Stackoverflow.com