Running AngularJS initialization code when loading a view

When I load the view, I would like to run some initialization code in the appropriate controller.

For this, I used the ng-init directive for 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 this?

Next, I have a problem with the sequence of events occurring. In the view, I have a Save button that 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 loading a view, the isClean function is called before the init() function, so the isSaving flag is undefined . What can I do to prevent this?

+81
angularjs
Apr 22 '13 at 14:59
source share
4 answers

When your view loads, the corresponding controller is also associated with it. Instead of using ng-init just call your init() method on the controller:

 $scope.init = function () { if ($routeParams.Id) { //get an existing object } else { //create a new object } $scope.isSaving = false; } ... $scope.init(); 

Since your controller runs before ng-init , this also solves your second problem.

Fiddle




As John David Five mentioned, you may not want to attach this to $scope to make this method private.

 var init = function () { // do something } ... init(); 

See jsFiddle




If you want to wait for certain data to be pre-configured, move this data request for permission or add an observer to this collection or object and call the init method when your data meets your init criteria. Usually I delete the observer as soon as my data requirements are met, so the init function does not execute an accidental restart if the data you are observing changes and meets your criteria for triggering the init method.

 var init = function () { // do something } ... var unwatch = scope.$watch('myCollecitonOrObject', function(newVal, oldVal){ if( newVal && newVal.length > 0) { unwatch(); init(); } }); 
+125
Apr 22 '13 at 17:34
source share

Starting with AngularJS 1.5, we must use $onInit which is available on any AngularJS component. Taken from the component lifecycle documentation , since v1.5 is in its preferred way:

$ onInit () - is called on each controller after all the controllers on the element have been created and their bindings have been initialized (and before the pre & post binding functions for the directives of this element). This is a good place to enter the 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'; } }); 

>> Screenshot




An extended example of using the component life cycle:

The component life cycle enables us to efficiently process components. This allows us to create events, for example, the "init", "change" or "destroy" of the component. Thus, we can control the material, which depends on the life cycle of the component. This short example shows how to register and $rootScope register $rootScope event listener $on . Knowing that the $on on $rootScope on $rootScope will not be canceled when the controller loses its link in the view or is destroyed, we need to manually destroy $rootScope.$on listener. A good place to post this material is the $onDestroy life cycle of the $onDestroy 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(); } }); 

>> Demo screenshot

+24
Apr 08 '17 at 23:29
source share

Or you can simply initialize the built-in controller. If you use the init function built into the controller, it does not need to be defined in the scope. In fact, it can be executed independently:

 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 } } 
+17
Apr 22 '13 at 19:41
source share

In my projects, I use the following template:

 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 */ { // ... } }); 
+12
Jun 05 '15 at 11:31 on
source share



All Articles