How do I pass data to Angular routed components?

前端 未结 16 1099
挽巷
挽巷 2020-11-22 08:03

In one of my Angular 2 routes\'s templates (FirstComponent) I have a button

first.component.html

相关标签:
16条回答
  • 2020-11-22 08:23
    <div class="button" click="routeWithData()">Pass data and route</div>
    

    well the easiest way to do it in angular 6 or other versions I hope is to simply to define your path with the amount of data you want to pass

    {path: 'detailView/:id', component: DetailedViewComponent}
    

    as you can see from my routes definition, I have added the /:id to stand to the data I want to pass to the component via router navigation. Therefore your code will look like

    <a class="btn btn-white-view" [routerLink]="[ '/detailView',list.id]">view</a>
    

    in order to read the id on the component, just import ActivatedRoute like

    import { ActivatedRoute } from '@angular/router'
    

    and on the ngOnInit is where you retrieve the data

    ngOnInit() {
           this.sub = this.route.params.subscribe(params => {
            this.id = params['id'];
            });
            console.log(this.id);
          }
    

    you can read more in this article https://www.tektutorialshub.com/angular-passing-parameters-to-route/

    0 讨论(0)
  • 2020-11-22 08:23

    One fine solution is to implement a Guard with canActivate method. In this scenario you can fetch data from a given api and let user access the component describe in the routing file. In the meantime one can set the data property of the route object and retrieve it in the component.

    Let say you have this routing conf:

    const routes: Routes = [
        { path: "/:projectName", component: ProjectComponent, canActivate: [ProjectGuard] }
    ]`
    

    in your guard file you may have:

    canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot)
    : Observable<boolean> | Promise<boolean> | boolean {
    return this.myProjectService.getProject(projectNameFoundElsewhere).pipe(
      map((project) => {
        if (project) {
          next.data = project;
        }
        return !!project;
      }),
    );
    

    }`

    Then in your component

    constructor(private route: ActivatedRoute) {
        this.route.data.subscribe((value) => (this.project = value));
    }
    

    This way is a bit different than passing via a service since service keep the value in a behaviorSubject as long as it is not unset. Passing via tha guard make the data available for the current route. I havent check if the children routes keep the data or not.

    0 讨论(0)
  • 2020-11-22 08:26

    update 4.0.0

    See Angular docs for more details https://angular.io/guide/router#fetch-data-before-navigating

    original

    Using a service is the way to go. In route params you should only pass data that you want to be reflected in the browser URL bar.

    See also https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

    The router shipped with RC.4 re-introduces data

    constructor(private route: ActivatedRoute) {}
    
    const routes: RouterConfig = [
      {path: '', redirectTo: '/heroes', pathMatch : 'full'},
      {path : 'heroes', component : HeroDetailComponent, data : {some_data : 'some value'}}
    ];
    
    class HeroDetailComponent {
      ngOnInit() {
        this.sub = this.route
          .data
          .subscribe(v => console.log(v));
      }
    
      ngOnDestroy() {
        this.sub.unsubscribe();
      }
    }
    

    See also the Plunker at https://github.com/angular/angular/issues/9757#issuecomment-229847781

    0 讨论(0)
  • 2020-11-22 08:30

    Solution with ActiveRoute (if you want pass object by route - use JSON.stringfy/JSON.parse):

    Prepare object before sending:

    export class AdminUserListComponent {
    
      users : User[];
    
      constructor( private router : Router) { }
    
      modifyUser(i) {
    
        let navigationExtras: NavigationExtras = {
          queryParams: {
              "user": JSON.stringify(this.users[i])
          }
        };
    
        this.router.navigate(["admin/user/edit"],  navigationExtras);
      }
    
    }
    

    Receive your object in destination component:

    export class AdminUserEditComponent  {
    
      userWithRole: UserWithRole;      
    
      constructor( private route: ActivatedRoute) {}
    
      ngOnInit(): void {
        super.ngOnInit();
    
          this.route.queryParams.subscribe(params => {
            this.userWithRole.user = JSON.parse(params["user"]);
          });
      }
    
    }
    
    0 讨论(0)
  • 2020-11-22 08:31

    Angular 7.2.0 introduced new way of passing the data when navigating between routed components:

    @Component({
      template: `<a (click)="navigateWithState()">Go</a>`,
    })
    export class AppComponent  {
      constructor(public router: Router) {}
      navigateWithState() {
        this.router.navigateByUrl('/123', { state: { hello: 'world' } });
      }
    }
    

    Or:

    @Component({
      selector: 'my-app',
      template: `
      <a routerLink="/details" [state]="{ hello: 'world' }">Go</a>`,
    })
    export class AppComponent  {}
    

    To read the state, you can access window.history.state property after the navigation has finished:

    export class PageComponent implements OnInit {
      state$: Observable<object>;
    
      constructor(public activatedRoute: ActivatedRoute) {}
    
      ngOnInit() {
        this.state$ = this.activatedRoute.paramMap
          .pipe(map(() => window.history.state))
      }
    }
    
    0 讨论(0)
  • 2020-11-22 08:31

    say you have

    1. component1.ts
    2. component1.html

    and you want to pass data to component2.ts.

    • in component1.ts is a variable with data say

        //component1.ts
        item={name:"Nelson", bankAccount:"1 million dollars"}
      
        //component1.html
         //the line routerLink="/meter-readings/{{item.meterReadingId}}" has nothing to 
        //do with this , replace that with the url you are navigating to
        <a
          mat-button
          [queryParams]="{ params: item | json}"
          routerLink="/meter-readings/{{item.meterReadingId}}"
          routerLinkActive="router-link-active">
          View
        </a>
      
        //component2.ts
        import { ActivatedRoute} from "@angular/router";
        import 'rxjs/add/operator/filter';
      
        /*class name etc and class boiler plate */
        data:any //will hold our final object that we passed 
        constructor(
        private route: ActivatedRoute,
        ) {}
      
       ngOnInit() {
      
       this.route.queryParams
        .filter(params => params.reading)
        .subscribe(params => {
        console.log(params); // DATA WILL BE A JSON STRING- WE PARSE TO GET BACK OUR 
                             //OBJECT
      
        this.data = JSON.parse(params.item) ;
      
        console.log(this.data,'PASSED DATA'); //Gives {name:"Nelson", bankAccount:"1 
                                              //million dollars"}
         });
        }
      
    0 讨论(0)
提交回复
热议问题