Ciel Ciel - 2 months ago 13
AngularJS Question

Child route keeps triggering parent when ui-sref-active-eq is used (angular-ui-router)

I have a route in

angular-ui-router
that has child routes; I want links to those child routes to only be visible while on the parent route. They are present on a menu that is visible for the whole application, but each link depends on a url parameter in the parent to work, so it's imperative that they not be clickable when that parameter doesn't exist.

So, the setup is like this;

.state('route1', {
url: '/route1/:id',
views: { 'main@': { template: '<route1-component></route1-component>' } }
})
.state('route1.child1', {
url: '/child1',
views: { 'main@': { template: '<route1-child1-component></route1-child1-component>' } }
})


I've gotten the functionality of hiding them to work using the
ui-sref
in combination with
ui-sref-active-eq
, using this layout...

<div ui-sref="route1" ui-sref-active-eq="visible" hidden>
<a ui-sref="route1.child1" ui-sref-opts="{ location: true, inherit: true, relative: true }">CHILD 1</a>
</div>


This works fine at first; The link is only visible when we're on the
route1
route. The url it shows is
#/route1/1/child1
, including the
:id
parameter of the current url.

But when I click on the link, the URL flashes as
#/route1/1/child1
for a brief instant, but then
route1
renders again.

If I remove the
ui-sref-active-eq
portion, it correctly routes to the child route. But then I've got the problem of it not being hidden otherwise.

Is there anything that can be done?

Please note, I am using exclusively angular 1.5+ components. I'm not using normal controllers or directives at all. It's all 100% components.

It's not quite perfect, but this is an example of how things are laid out, and I tried to make it clear how they're expected to function. I can't seem to get the
$state
within the directive to observe changes. https://plnkr.co/edit/rxjVbckhwxdYPRAX4uiU?p=preview

Answer

following adds a controller to your sidenav component and uses $stateChangeSuccess event and $state.includes() to update a boolean passed to ng-show

  .component('sidenav', {
    controller: function ($rootScope,$state) {
      var vm = this;
      vm.isRoute1=$state.includes('route1');
      $rootScope.$on('$stateChangeSuccess', function(evt, to, from){
          vm.isRoute1=$state.includes('route1');
      });            
   },
    template: `
        <div  ng-show="$ctrl.isRoute1">
          <a ui-sref="route1.child1" ui-sref-opts="{ location: true, inherit: true, relative: true }">
            ROUTE 1 CHILD 1 LINK
          </a>
        </div>`

  })

I think this is the behavior you want ... not 100% sure though

DEMO