angular / router

The Angular 1 Component Router
MIT License
665 stars 135 forks source link

Can't Access actual $router.name or $routeParams from child component #395

Open tomer78 opened 8 years ago

tomer78 commented 8 years ago

Hi, I'm working with Angular 1.4.7. I'm trying to get current route name from $router.name or get the route params from $routeParams From within a child component. $router.name also return "/" and $routeParams does not contain any parameter. Is there any other way to get this to work?

ArniDzhan commented 8 years ago

Hi tomer78, can you share your controllers? for instance in my main I have:

$router.config([
    {
      path: '/',
      redirectTo: '/home'
    },
    {
      path: '/home',
      component: 'home'
    },
    {
      path: '/:entity/list',
      component: 'list'
    },
    {
      path: '/:entity/:id/:tab',
      component: 'details'
    }
  ]);

and in details.js :

function detailsController($routeParams) {
  console.log($routeParams.entity, $routeParams.id);
}

and it works as expected. (I am on 1.5 btw)

tomer78 commented 8 years ago

This works ,BUT if you would have a directive inside the details component, and from that directive you would try to get to $routeParams.id you would get undefined. Same thing if you would try to get $router.name from within that directive you would get the root ("/"). It seems like those values are not propagated to inner directives

ArniDzhan commented 8 years ago

just pass it as a param to directive.

ArniDzhan commented 8 years ago

how did you define child components btw?

tomer78 commented 8 years ago

my routing looks like that: $router.config([ {path: '/', redirectTo: 'category/full'}, {path: '/category/:id', component: 'category'}, {path: '/word/:categoryId/:wordId', component: 'word'} ]);

I have a folder in the components folder that contain the CategoryController and the Category.html. The Category.html contains a certain directive that need to know the current route state and the current route params throughout the application.

I've also tried to place that directive the index.html,but got the same result

ArniDzhan commented 8 years ago

ok it looks like you are not using child component but just have a directive inside of your controller, as mentioned just pass params to directive something like

function detailsController($routeParams) {
  this.id = $routeParams.id;
}

and then in your html

<my-directive id="details.id"></my-directive>
tomer78 commented 8 years ago

ok. it means i don't have the option to get current route params from a directive. What if i have an header directive for example,in the index.html. That directive should show certain navigation buttons according current route path or params. I can't pass the directive any parameter cause its in the root html. do i need to use the $location service in order to get the route params and current route?

ArniDzhan commented 8 years ago

you can pass params to root html using rootScope or a service which stores current route in a property. You can add canActivate to your main controller (where you have your router config) and run some logic there and pass required value to the scope where it will be used by html which you have in the root here is example of menu updated using data returned from api. index.html

<body ng-controller="RouteController as route">
<top-header></top-header>
<div class="container-fluid home_mainContainer">
    <div class="row">
        <div class="col-xs-2 home__leftColumn">
            <left-menu ng-if="route.allowedMenuItems" entities="route.allowedMenuItems"></left-menu>
        </div>
        <div class="col-xs-10 home__rightColumn" ng-viewport></div>
    </div>
</div>

router.js

layoutsModule.controller('RouteController', function($router, MetaDataService) {
  'ngInject';

  $router.config([
    {
      path: '/:entity/:id/:tab',
      component: 'details'
    }
  ]);

  const vm = this;
  MetaDataService.getMetaData().then( () => {

    vm.allowedMenuItems = MetaDataService.allowedModules;

  });
});

note I am using ES6 syntax you may need to change it to ES5. hope that helps

tomer78 commented 8 years ago

OK. I'll do it. I Appreciate the help.