Rudziankoŭ Rudziankoŭ - 6 days ago 6
AngularJS Question

UI-router: deal with nested controllers

I have following config:

.state("addUser", {
url: "/addUser",
templateUrl: "users/add-user.html",
controller: "AddUserParent",
controllerAs: "$ctrl",
abstract: true
})
.state("addUser.General", {
url: "/General",
templateUrl: "users/add-user-general.html",
controller: "AddUser",
controllerAs: "$ctrl",
})
.state("addUser.Cost", {
url: "/Cost",
templateUrl: "users/add-user-cost.html",
controller: "AddUser",
controllerAs: "$ctrl",
})
.state("addUser.Notes", {
url: "/Notes",
templateUrl: "users/add-user-notes.html",
controller: "AddUser",
controllerAs: "$ctrl",
})


And following parent controller:

angular
.module("users")
.controller("AddUserParent", AddUserParent);

AddUserParent.$inject = ["usersSrv", "stateRouter"];
function AddUserParent(usersSrv, stateRouter) {
let $ctrl = this;
$ctrl.navigate = stateRouter.navigate;
$ctrl.user = {};

$ctrl.addUser = function() {
usersSrv.addUser($ctrl.user);
console.log($ctrl.user);
$ctrl.navigate('home');
}
}


Child controller
AddUser
is just empty. When I fill in:

<input type="text" ng-model="$ctrl.user.name">
<input type="text" ng-model="$ctrl.user.location">


in
addUser.General
state and switch to
addUser.Cost
I lose all
$ctrl.user
data. Why does it happen so? How to fix this?

Answer

Its because when you navigate to another state even if the controller is the same, the controller gets reloaded which results in data loss. so you have multiple options to achieve that.

  • you may use services,
  • events
  • shared master controller
  • or passing parameter to the controller

Please check out nested views section of angular-ui-router it will give you some insight to achieve passing parameters to controllers.

or you can configure the states like this so that all the states use the same master controller.

  .state("addUser.General", {
        url: "/General",
        templateUrl: "users/add-user-general.html"
    })
    .state("addUser.Cost", {
        url: "/Cost",
        templateUrl: "users/add-user-cost.html"
    })
    .state("addUser.Notes", {
        url: "/Notes",
        templateUrl: "users/add-user-notes.html"
    })

because you didn't specify controller on state definition, all the child states use the same master controller AddUserParent

Comments