angular / router

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

Router params with Angular2 & Typescript #353

Open tbekaert opened 9 years ago

tbekaert commented 9 years ago

I've used this repo to create a project using the new router and angular2 with typescript.

Know, I want to add a new route with parameters but can't get it to work.

I have a simple component named Page

import { Component, View } from 'angular2/angular2';

@Component({
    selector: 'page'
})

@View({
    templateUrl: 'app/components/page/page.html',
    directives: []
})

export class Page {
    id:any;

    constructor() {
        console.log(this);
    }
}

And I just add a new route in my RouteConfig:

export var routes: Array<IRoute<any>> = [
    {
        component: Home,
        path: '/',
        as: 'home'
    },
    {
        component: Todos,
        path: '/todos',
        as: 'todos'
    },
    {
        component: Page,
        path: '/page/:id',
        as: 'page'
    }
]

But when I try to access this route using <a router-link="page" router-params="{id:5}">Page</a>, I get this error:

Route generator for 'id' was not included in parameters passed.

What am I doing wrong? Is there any example using the new router with angular2 and routes with parameters?

brtnshrdr commented 9 years ago

You have to use the following syntax:

<a router-link="page" [router-params]="{'id':5}">Page</a>

Noticed the parameter wrapped in square brackets []

gnomeontherun commented 9 years ago

I was unable to get the router-params directive to work (its not a directive at least in the current build), but was able to use router-link to pass params like below:

[router-link]="['/page', {id: 5}]"

This builds the correct href on the anchor tag, but clicking on the link changes the URL, but doesn't load the component. This is how the spec is doing it https://github.com/angular/angular/blob/a9a552c112da1397a0122acdbecbd52bc88e1906/modules/angular2/test/router/outlet_spec.ts#L187

brtnshrdr commented 9 years ago

You are correct in the way params now work. This commit shows when the test cases were updated to reflect that: https://github.com/angular/angular/commit/f66ce096d8d908fcc0a643a14412136e74025c3d#diff-3ae141b53be9d9a0a7576cdbcc350ff1

gnomeontherun commented 9 years ago

I'm building a stock app, and I can directly load the /stocks/:symbol url (/stocks/goog), and it renders the component. However, when I click a link using [router-link]="['/stocks', {symbol: stock.symbol}]" the url changes but the component does not render. I have the config below if that helps. I'm unsure why clicking the link doesn't render the Stock component and if it is a bug or something I've setup incorrectly.

@RouteConfig([
  {path: '/stocks/:symbol', as: 'stock', component: Stock}
])

And the component, simplified.

import {Component, View} from 'angular2/angular2';
import {RouterLink, routerInjectables} from 'angular2/router';

@Component({
  selector: 'summary',
  properties: ['stock: symbol'],
  viewInjector: [routerInjectables]
})
@View({
  directives: [RouterLink],
  template: `<a [router-link]="['/stock', {symbol: stock.symbol}]">View {{stock.name}}</a>`
})
export class Summary {
}
cghislai commented 9 years ago

I experience a similar behaviour when mixing navigation using router and location.

If I have a route {path: '/test/:name', component: ChildComponent, as: 'test'}, and a ChildComponent like this:

import {Component, View, Inject} from 'angular2/angular2';
import {Router, RouteParams, RouterLink, Location} from 'angular2/router';

@Component({
    selector: 'child'
})
@View({
    template: `<div>
      Im child named : {{ name }}<br/>
      <span [hidden]="!locationChanged">Location changed</span>
      <span [hidden]="!routeChanged">Route changed</span>
      <a [router-link]="['/test', {name: 'jon'}]">To Jon</a>
      <a [router-link]="['/test', {name: 'alphonse'}]">To Aplhonse</a>
      <a [router-link]="['/test', {name: 'Lizbeth'}]">To Lizbeth</a>
      <a (click)="onAction()">To Paul</a>
  </div>`,
    directives: [RouterLink]
})
export class ChildComponent {
    name:string;
    router:Router;
    location:Location;

    locationChanged:boolean;
    routeChanged:boolean;

    constructor(params:RouteParams, router:Router, location:Location) {
        this.name = 'child';
        this.router = router;
        this.location = location;
        this.fetchNameFromParams(params);

        this.locationChanged = false;
        this.routeChanged = false;

        this.location.subscribe(this.onLocationChanged, this.onLocationChanged, ()=>{
            console.log("returned");
        });
        this.router.subscribe(this.onRouteChanged);
        console.log("constructor");
    }

    fetchNameFromParams(params:RouteParams) {
        this.name = params.get('name');
    }

    onLocationChanged(path) {
        console.log('location changed');
        this.locationChanged = true;
    }

    onRouteChanged(path) {
        console.log('route changed');
        this.routeChanged = true;
    }

    onAction() {
        this.name = 'paul';
        this.location.go('/test/paul');
    }
}

Then, if you go through a router link to say Lisbeth, then click 'to Paul', then click back on Lisbeth, the url will change but the component will not be instantiaed again, and so won't update the name field. This could be fine if the component could listen to route or location changes, but as you can see in this example none of the callback are ever called.

brycepj commented 8 years ago

I'm seeing the same thing as @cghislai

horyd commented 8 years ago

Hey @cghislai, try adding the router lifecycle hooks routerCanReuse, routerOnReuse and routerOnActivate. I've found that routerCanReuse can default to true, which prevents the constructor from re-running as the component hangs around.

KostyaTretyak commented 8 years ago

I resolve a similar problem by removing the slash in my view after PostAction

<a [routerLink]="['/Post/PostAction', {action: 'read', id: post.id}]">{{ post.title }}</a>
mahendratyagi commented 8 years ago

@cghislai Route subscribe was help me :)

Thanks

mpetkov commented 8 years ago

Sorry to comment on old thread, but is it possible to set the routerLink in the component code instead of the template?

mahendratyagi commented 8 years ago

Yes in Angular2 you can use the NAVIGATION to move to any other route but unfortunately it was in beta version and in RC version the team has not updated the document.so mean time they uploads the document for the router you can user location.

FreshTouch commented 6 years ago

You can use this. Angular2+/4/5 - navigate with data https://github.com/Hipparch/Angular2-navigate-with-data