angular-breadcrumb icon indicating copy to clipboard operation
angular-breadcrumb copied to clipboard

Breadcrumbs not triggering re-render when changing between parent and child states

Open haxxxton opened this issue 9 years ago • 9 comments

I was struggling to figure out why when toggling between child and parent states the breadcrumbs werent updating (they would stay as the page rendered them if deep linking into a child state, or at the parent state if going to a new 'root' state)

My state config looked like:

$stateProvider
    .state('app',{
        url: '/',
        abstract: true,
        views: {
        }
    })
    .state('app.foo', {
        url: 'foo',
        views: {
            'content@': {
                templateUrl: partialsUrl + 'foo.main.html',
                controller: 'FooController',
                controllerAs: 'vm'
            }
        },
        ncyBreadcrumb: {
            label: 'menu.foo'
        }
    })
    .state('app.foo.add', {
        url: '/add',
        views:{
            'content@overlay':{
                templateUrl: partialsUrl + 'foo.add.html',
                controller: 'FooAddEmployeeController',
                controllerAs: 'vm'
            }
        },
        ncyBreadcrumb: {
            label: 'menu.foo.add'
        }
    })
    .state('app.bar', {
        url: 'bar',
        views: {
            'content@': {
                templateUrl: partialsUrl + 'bar.main.html',
                controller: 'BarController',
                controllerAs: 'vm'
            }
        },
        ncyBreadcrumb: {
            label: 'menu.bar'
        }
    })

in the base template i used the breadcrumb directive

<div ncy-breadcrumb="ncy-breadcrumb"></div>

If i deep linked into app.foo.add the breadcrumbs would correctly show Home \ Foo \ Add however, clicking on a button that used ui-sref="app.foo" would leave the breadcrumbs as above.

I realised that breadcrumbs triggers a re-render on $viewContentLoaded. Which wasnt being triggered when the states changed between child and parent views. When i changed all references to $stateChangeSuccess this solved the problem.

Is there a reason that $viewContentLoaded is used instead of $stateChangeSuccess? am i likely to encounter any issues with this?

haxxxton avatar Aug 24 '16 04:08 haxxxton

I think there was a similar issue in #154

CSchulz avatar Aug 24 '16 07:08 CSchulz

@CSchulz good pick up! title of the other issue didnt seem related, but the solution appears the same. Questions still stand, but happy to be merged/marked as duplicate if they can be added to the other issue.

Is there a reason that $viewContentLoaded is used instead of $stateChangeSuccess? am i likely to encounter any issues with this?

haxxxton avatar Aug 24 '16 23:08 haxxxton

@haxxxton 'When i changed all references to $stateChangeSuccess this solved the problem.'

How do you do that ? :)

ptitdje45 avatar Nov 29 '16 07:11 ptitdje45

@ptitdje45, i created a fork of this repo and did a find and replace for all instances of $viewContentLoaded with $stateChangeSuccess. It is currently failing on 3 tests as part of the Breadcrumb directive with multiple-interpolation conf test

  • renders the correct state chain and views content,
  • renders the correct state chain and views content, and
  • renders the correct state chain and views content

If this use case is not something you need to worry about, feel free to use my code here: https://github.com/haxxxton/angular-breadcrumb

haxxxton avatar Nov 30 '16 00:11 haxxxton

@haxxxton Thanks buddy :)

ptitdje45 avatar Nov 30 '16 08:11 ptitdje45

What I find strange is that the directive and the service both have $rootScope listen for $viewContentLoaded, yet the handlers never fire. Yet, when I go into any controller of mine, inject $rootScope, and have it listen for the same event (and use console.log as the handler), the handler gets fired multiple times.

edit: On closer inspection, $viewContentLoaded is getting fired off long before the listeners are bound.

My routing setup currently has an .otherwise() rule set up to redirect to a child state temporarily while I set up routes properly. In this case, $stateChangeSuccess never fires because the state never changes, and thus I have breadcrumbs with empty labels. I'm guessing that $viewContentLoaded is used to try to handle both first-load and route change situations all at once, but clearly this isn't working completely.

p0lar-bear avatar Jun 27 '17 17:06 p0lar-bear

@p0lar-bear did you have a go using my suggested change of $stateChangeSuccess? it might be nice to see if that is a viable solution in other people's implementations

haxxxton avatar Jun 28 '17 00:06 haxxxton

In my case, it wouldn't have done anything. It doesn't seem like $stateChangeSuccess is fired when the app is first loaded and the initial state is determined.

I will keep this in mind for once my app's states are properly defined, though.

Also, I think it's prudent to call attention to the fact that these state change events were deprecated with ui-router v1.0. The ui-router team has provided polyfills for them, and while this is a valid stopgap, this breadcrumb module should be updated to use the transition hook API instead of these events.

p0lar-bear avatar Jun 29 '17 17:06 p0lar-bear

I thing I have the same problem. For example, I have the breadcrum navigation : a > b > c a is the parent of b, b the parent of c Each state (a, b and c) have their own View and Controller. When a user navigate from a to b the Controller of b is triggered correctly. Same thing from b to c But when a user navigate from c to b, the Controller of b is never triggered.

@haxxxton I've tried 2 things :

  1. in angular-breadcrumb.js I've replaced all instances of $viewContentLoaded with $stateChangeSuccess
  2. I've used your implementation from your repo

In both cases it's not fixed anything.

Any idea ? Thanks

JuDev3 avatar Oct 26 '18 12:10 JuDev3