【问题标题】:Passing dynamic data through Angular 2 route通过 Angular 2 路由传递动态数据
【发布时间】:2017-04-26 23:51:28
【问题描述】:

可以将静态数据传递给 Angular 2 路由而不在 URL 上显示。

但是我怎样才能以同样的方式传递动态数据/对象呢?

【问题讨论】:

  • 我假设您想为用户体验目的传递简单数据,对吧?

标签: angular typescript angular2-routing


【解决方案1】:

您可以使用状态对象从Angular7.2传递动态数据

在组件中使用 navigateByUrl 发送任何数据

  public product = { id:'1', name:"Angular"};
  gotoDynamic() {
     this.router.navigateByUrl('/dynamic', { state: this.product });
  }

并使用 history.state 读取它

In dynamicComponent

    ngOnInit() {
           this.product=history.state;
    }  

参考: Passing Dynamic Data

【讨论】:

    【解决方案2】:

    您可以使用解析器。解析器返回的数据可用于路由,就像路由配置中的静态 data 一样

    例子见https://angular.io/guide/router#resolve-guard

    @Injectable()
    export class CrisisDetailResolve implements Resolve<Crisis> {
      constructor(private cs: CrisisService, private router: Router) {}
      resolve(route: ActivatedRouteSnapshot): Promise<Crisis>|boolean {
        let id = route.params['id'];
        return this.cs.getCrisis(id).then(crisis => {
          if (crisis) {
            return crisis;
          } else { // id not found
            this.router.navigate(['/crisis-center']);
            return false;
          }
        });
      }
    }
    
    path: '',
    component: CrisisListComponent,
    children: [
      {
        path: ':id',
        component: CrisisDetailComponent,
        canDeactivate: [CanDeactivateGuard],
        resolve: {
          crisis: CrisisDetailResolve
        }
      },
    
    ngOnInit() {
      this.route.data
        .subscribe((data: { crisis: Crisis }) => {
          this.editName = data.crisis.name;
          this.crisis = data.crisis;
        });
    }
    

    【讨论】:

      【解决方案3】:

      最好结合前面两个答案:

      • Günter Zöchbauer 的answer 包含一个自定义解析器,它是一个message enricher:给定一个以/crisis/15 结尾的URL,它将把危机的完整数据传递给CrisisComponent。我们需要解析器,但我认为 OP 不希望在 URL 中显示任何数据。
      • Tsadkan Yitbarek 的answer 提出了一种数据存储和通信服务(类似于 Redux/Flux 中的 Store)。他正确地认为这太过分了,但我们需要将信息存储在某个地方。

      因此,解决方案是将共享数据放入解析器本身:与组件不同,服务是长期存在的,并且始终只有一个实例,因此解析器中的数据是安全的:

      // --- CrisisDetailResolve --- 
      // In the function body, add:
      private currentCrisisId: number | string
      
      set(crisisId: number | string) {
         this.currentCrisisId = crisisId 
      }
      
      // change line 5 of CrisisDetailResolve:
       let id: number = 0 + this.currentCrisisId
      
      // -- In your code -- 
      // You can now navigate while hiding 
      // the crisis number from the user:
      private click(crisisId : string | number) {
        // tell resolver about the upcoming crisis:
        this.crisisResolve.set(crisisId)  
        // navigate to CrisisDetail, via CrisisResolve:
        this.router.navigate(['/crisisDetail')
        // CrisisDetail can now receive id and name in its NgOnInit via `data`,
        // as in Günter Zöchbauer's answer and the Angular docs 
      }
      

      另见Angular Docs on Routing

      【讨论】:

        【解决方案4】:

        你可以做两件事 1.不推荐,但使用数据作为路由器参数并传递,

        { path: 'some:data', component: SomeComonent }
        

        并用作

        let data = {"key":"value"}
        this.router.navigate(['/some', data)
        

        2.而不是通过路由参数传递数据(因为数据可能很大并且容易受到攻击,因为它可以被用户查看)

        @Injectable()
        export class SomeService {
          data = {};
        }
        
        @Component({...
           providers: [SomeService]
        export class Parent {
          constructor(private someService:SomeService) {}
        
          private click() {
            this.someService.data = {"key":"value"}
          }
        }
        

        【讨论】:

        • 你不觉得共享服务对于这么简单的对象来说太过分了
        • 是的,我认为,但如果对象太大,我更喜欢这个。
        • @tsadkanyitbarek 是 localhost:0000/home/id=2 和 localhost:0000/page1/id=2 的这些工作,其中 id 是静态数据,id 号是动态的。
        猜你喜欢
        • 2016-09-06
        • 2016-05-30
        • 1970-01-01
        • 2018-07-12
        • 2017-02-28
        • 1970-01-01
        • 1970-01-01
        • 2015-03-20
        • 2017-04-23
        相关资源
        最近更新 更多