ncuillery / angular-breadcrumb

Generate a breadcrumb from ui-router's states
http://ncuillery.github.io/angular-breadcrumb/
MIT License
785 stars 183 forks source link

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

Open haxxxton opened 8 years ago

haxxxton commented 8 years ago

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?

CSchulz commented 8 years ago

I think there was a similar issue in #154

haxxxton commented 8 years ago

@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?

ptitdje45 commented 7 years ago

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

How do you do that ? :)

haxxxton commented 7 years ago

@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

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

ptitdje45 commented 7 years ago

@haxxxton Thanks buddy :)

p0lar-bear commented 7 years ago

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.

haxxxton commented 7 years ago

@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

p0lar-bear commented 7 years ago

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.

JuDev3 commented 5 years ago

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