Loss of form input on controller click again

I have a simple multi-user Angular app that implements a wizard, so every time the user clicks the Next button, the app goes to the next view, also for the Back button. I have a config $routeProvider

that links all views to the same controller. Each view is a piece of a huge form with input fields, and $routeProvider

controls navigation through them:

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider.when('/salespoints', {
        templateUrl: 'salespoints',
        controller: 'main'
    })
    .when('/users', {
        templateUrl: 'users',
        controller: 'main'
    })
    .otherwise({
        templateUrl: 'partner',
        controller: 'main'
    });

    $locationProvider.hashPrefix('');
}]);

      

The problem is that every time the user clicks Next or Previous, the controller is called, so any changes $scope

that were made in the previous steps are simply lost:

app.controller('main', ['$scope', function ($scope) {
    console.log('controller invoked'); // appears each time a user presses "Next" or "Back", hence re-instantiation of $scope
}]);

      

The app is small enough to switch to $rootScope

if every other method fails, but I just would like to avoid this as an anti-pattern.

What's the best way to keep it up $scope

to date with all the changes made from the very beginning of the application instance's lifecycle, and without re-creating it every time the view changes?

+3


source to share


3 answers


Use a service to save the form data and inject it into your controller.



angular.module('app').factory('formService', function () {
   var data = {};
   return {
      data: data
   };
});

angular.module('app').controller('ctrl', function(formService) {
   this.formData = formService.data;
});

      

+4


source


Angular controllers are executed on every new one ng-controller

in your template.

Angular services only execute once , the first time you need it, because they are singleton .



As such, angular services should be used to store data, especially data that is shared between multiple controller instances (even if it is the same controller definition as in your example).

+1


source


So, per @ joao-leal's advice , I ported the data persistence to a new service and signed up for $scope

updates via $scope.$watch

. The general solution resulted in a rather simple piece of code:

app.factory('formPersistence', function () {
    var data = {};

    var get = function () {
        return data;
    };

    var set = function (updated) {
        data = updated;
    }

    var reset = function () {
        data = {};
    }

    return {
        get: get,
        set: set,
        reset: reset
    };
});

app.controller('main', ['$scope', 'formPersistence', function ($scope, formPersistence) {
    $scope.data = formPersistence.get();

    $scope.$watch('data', function () {                
        formPersistence.set($scope.data);
    });
}]);

      

+1


source







All Articles