user2173353
user2173353

Reputation: 4640

ui-router renders template before state changes

I have a nested state structure like this:

$stateProvider
        .state('main', {
            url: '',
            abstract: true,
            templateUrl: ...
            controller: mainController,
            resolve: {
                Resolve1: ...
                Resolve2: ...
            }
        })
        .state('main.state1', {
            url: '^/state1/:id/',
            templateUrl: ....
            controller: state1Controller,
            resolve: {
                Resolve11: ...
                Resolve22: ...
            },
        })
        .state('main.state2', {
        ....

From what I am seeing, when you are at state main.state1 and you navigate to the same state with another id parameter, the template for main.state1 is rendered fine but the template for main (the parent) is rendered before the state changes (I guess it doesn't wait for the data resolution of main.state1). This results to the view being rendered with the wrong data (more specifically, the state parameters that I use for generating links are wrong).

My mainController has the $stateParams and $state injected to it and that's where I get the data from.

Did anyone notice this before? Is this by design or is it a bug?

Is there any way to update the parent view with the latest data?

However, I would expect ui-router to wait for all data resolutions until it starts rendering the views (even the parent). I don't know if I am missing something here, but this is my understanding of the problem so far...

UPDATE:

I see now that a function that is involved in the view rendering (with interpolation) gets called many times, first with the old values and then with the new values. But the final result that I see on screen is using the initial data that were used when I first entered the 'main.*' state. This is SO weird.

UPDATE 2:

I have found that my links where not updated ONLY when using ui-sref (note that I was using parameters in the state href, e.g. ui-sref="main.state1({id:{{getId()}}})"). When switched to ng-href everything worked as expected.

I have no idea why, but that fixed the problem.

The odd thing was that the ui-sref was evaluated, but the link was not updated.

Go figure...

UPDATE 3:

This solution in turn caused other problems. Then the first click reloaded the application... So this is not the best fix...

Upvotes: 4

Views: 1435

Answers (2)

user2173353
user2173353

Reputation: 4640

The "solution" was to use ng-click with $state.go(), instead of links.

This appears to be a bug in ui-router.

Upvotes: 1

Chad Robinson
Chad Robinson

Reputation: 4623

ui-router transitions "through" the parent state to the child. That means main will be triggered, then main.state1. I ran into this myself where I was getting duplicate listeners and HTML DOM elements - main is actually running AT THE SAME TIME as main.state1. This behavior is by design, and AFAIK your only option is to design around it.

Upvotes: 0

Related Questions