3

I have three states: one abstract state and two concrete states inheriting from the abstract one. I am transitioning from one state to another and I noticed that the variables that were in the $scope in one state are no longer in $scope after I have transitioned to the other state: see $scope.signupForm.member.email below.

Can someone please advise?

My UI router configuration:

$stateProvider
    .state('signup', {
        abstract: true,
        views: {
            '@': {
                templateUrl: 'signup/views/signup.html'
            }
        }
    })
    .state('signup.form', {
        url: '/signup',
        views: {
            '@signup': {
                controller: 'SignupCtrl',
                templateUrl: 'signup/views/signup.form.html'
            }
        }
    })
    .state('signup.success', {
        url: '/signup/success',
        views: {
            '@signup': {
                controller: 'SignupCtrl',
                templateUrl: 'signup/views/signup.success.html'
            }
        }
    })

Relevant snippet from my controller:

signupService.signup($scope.signupForm)
                    .success(function () {
                        //TODO: issue with controller no longer being in scope: signupForm.member.email is not displayed in template
                        $state.go('signup.success');
                    });

My email input (from signup.form.html):

<input type="email" name="email" 
     placeholder="{{'SIGNUP_FORM_EMAIL' | translate}}"
     ng-model="signupForm.member.email" ng-required="true" 
     ng-pattern="EMAIL_PATTERN"
     class="form-control"/>

Where I try to display the email (from signup.success.html):

<div class="panel-body">
    success!
    check your email at: {{signupForm.member.email}}
</div>

edit 1:

If I pull up the controller one level - by putting it into the abstract state i.e. 'signup', then signupFormCtrl - the angular form controller - is undefined!

<form name="signupFormCtrl" ng-submit="signup()" novalidate>

edit 2:

This is what I tried:

 .state('signup', {
        abstract: true,
        views: {
            '@': {
                controller: 'SignupCtrl',
                templateUrl: 'signup/views/signup.html'
            }
        }
    })
    .state('signup.form', {
        url: '/signup',
        views: {
            '@signup': {
                templateUrl: 'signup/views/signup.form.html'
            }
        }
    })
    .state('signup.success', {
        url: '/signup/success',
        views: {
            '@signup': {
                templateUrl: 'signup/views/signup.success.html'
            }
        }
    })
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
balteo
  • 23,602
  • 63
  • 219
  • 412

2 Answers2

3

Thre is a working plunker

This is feasable with UI-Router built-in features. We will need to introduce controller for our base state:

.state('signup', {
    abstract: true, 
    templateUrl: 'signup/views/signup.html',
    controller: 'SignupBaseCtrl',
})

Inside of this controller we would define a Model inside of a $scope:

.controller('SignupBaseCtrl', ['$scope', function ($scope) { 
  $scope.signupForm = { member : { email : null }};
}])

And now, if we would work with a model like this:

{{signupForm.member.email}}

In any of our child states, we would be accesing the same model, the same reference object singupForm.

And how it is possible? how it is working? All is clearly explained here:

Scope Inheritance by View Hierarchy Only

Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).

It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states.

You can also check: Controller from Parent Layout is not access by child views

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
0

Data from one scope can not be accessed from a different scope. try using the rootScope for data that is to be used across scopes use $root in templates as in {{$root.signupForm.member.email}} and $rootScope in controllers as in $rootScope.signupForm.member.email

klvmungai
  • 804
  • 1
  • 12
  • 21