angular / router

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

Cannot access path params of a parent non-terminal Route from child routes #413

Open nitroduna opened 8 years ago

nitroduna commented 8 years ago

Angular 1.5.5 (ngComponentRouter)

When you configures a routing hierarchy using non terminal components routes, you cannot get the path parameters resolved by the parent non-terminal routes in child routes.

See example code below

There should be a way to do this because if your non terminal route has been created, the parent non terminal routes already have resolved the path params, and sometimes the terminal routes needs all the params to do its works, for example to call a REST API with nested identities.

The only way would be to get the path from $location and parse the route, but that is the work of the path params.

We found a workaround requiring the parent component controller this way:

require: {
    // Parent component controller containing the list of operations
    $dataset: '^dataset',
},

The parent component can save its resolved path params in the controller so that the child component can get the params of the whole route.

This is not a very elegant solution and the problems is that only works in $routerOnActivate.

You cannot access the required parent controller from $canActivate because is an static method, the controller of your component has not been created and you cannot access required component.

I think it is needed a solution to get the params of the whole route of a hierarchy of components because the solution would be to not use non-terminal components and declare all your routes in only one component, the $rootRouter, you'd lose the very good mechanisms of declaring hierarchical components.

EXAMPLE

module.component('main', {
    template: '<ng-outlet></ng-outlet>',
    $routeConfig: [
        {path: '/:organization/:dataset/...', component: 'dataset', name: 'Dataset'},
    ],
});

module.component('dataset', {
    template: '<ng-outlet></ng-outlet>',
        $routeConfig: [
            {path: '/:operation', component: 'operation', name: 'Operation' },
        ],
})

module.component('operation', {
    template: '<div>operation</div>',

    $canActivate: ['$nextInstruction', function(next) {
        var operation_name = decodeURIComponent(next.params.operation);

        // ERROR: you cannot get the path params resolved by the parent non-terminal
        //                component "dataset", there is no way to get them, and it seems to not
        //                have sense because to show this component the parent component
        //                has resolved the route and has the params.
        var dataset_name = decodeURIComponent(next.params.dataset); 
    }],

    controller: [function() {
        var $ctrl = this;
        $ctrl.$routerOnActivate = function(current, previous) {
            var operation_name = decodeURIComponent(next.params.operation);

           // ERROR: you cannot get the path params resolved by the parent non-terminal
           //                component "dataset", there is no way to get them, and it seems to not
           //                have sense because to show this component the parent component
           //                has resolved the route and has the params.
           var dataset_name = decodeURIComponent(next.params.dataset); 
    }],
})
nitroduna commented 8 years ago

I thought that this was the repository of the component router included in Angular 1.5.5, but I'm not so sure now.

amritk commented 8 years ago

Heres a little hack, inject the $rootRouter then: $rootRouter.currentInstruction.child.component.params