【问题标题】:Non-Url Parameters in Angular 2 RouterAngular 2 路由器中的非 URL 参数
【发布时间】:2017-08-04 11:14:55
【问题描述】:

在 angular 1.* 中,我使用的是 ui-router,并且能够将 NON URL 参数 从一种状态传递到另一种状态。通过非 URL 参数,我的意思是传递一些不会出现在 URL 上的参数(对用户来说完全透明)。

在 Angular 1.* 中执行此操作的方法是定义这样的状态(stateToRedirect 是非 url 参数)

   $stateProvider
    .state('LOGIN_STATE', {
      url: `login`,
      component: 'login',
      params: {
        stateToRedirect: 'home'
      }
    });

像这样改变状态:

  $state.go('LOGIN_STATE', {
    stateToRedirect: 'OTHER_STATE',
  });

在 LOGIN_STATE 中,我可以这样做访问这个参数:

$stateParams.stateToRedirect;

我正在尝试为 Angular 2 路由器找到相同的行为,我的理解是 Angular 2 路由器已经改进了很多,我们可能不需要使用 ui-router-ng2。

所以我的问题是:如何在 Angular 2 路由器中重现上述行为?

This question 似乎是我想要的,但我不希望 URL 中的参数和路由上的“数据”属性看起来不错,但我找不到有关如何动态设置它的文档。

【问题讨论】:

    标签: angular angular2-routing


    【解决方案1】:

    您要问的问题更多是关于component to component communication,而不是路由本身。您需要将数据从一个组件(与特定路由关联)传递到另一个组件(与另一个路由关联)。

    组件到组件的通信可以通过以下方式实现

    1. 具有父子关系的组件可以通过@Input() 和@Output() 装饰器和事件发射器传递数据

    2. Via the use of a service。不共享位于同一模块中的父子关系的组件可以通过服务共享数据,或者通过使用 Observable 序列(具有生产者-消费者模型)或通过在变量中设置数据并相应地读取。通过向根(或两者的父)模块注册服务,可以将此方法扩展到驻留在不同模块中的组件。

    3. 通过路由器。数据可以通过路由器作为路径参数传递,例如:my/path/thisisapathvalueoptional parameters(使用矩阵表示法),例如my/path;item=hello;item2=world,或通过查询字符串参数,例如my/path?item=hello&item2=world。您还可以使用 resolve guards 解析特定组件的数据,它可以解析静态数据、从服务器检索的数据、通过函数解析等。

    对于您的场景,您最可能需要的是在源组件与目标组件之间传递数据的服务,因为即使使用解析防护来解析数据,您也需要额外的服务来临时存储您需要传递的数据。

    【讨论】:

      【解决方案2】:

      可以使用路由解析器来做到这一点,它会比你的 AngularJs 实现更复杂一些,但应该允许你做你想做的事。

      角度文档

      https://angular.io/guide/router#resolve-pre-fetching-component-data

      Angular 大学 YouTube 频道的视频示例(无从属关系)

      https://www.youtube.com/watch?v=6xmCNfPP90E

      【讨论】:

        【解决方案3】:

        如果两个组件属于同一个模块,您是否考虑过使用服务来代替?在服务中添加一个模型(或参数),将其作为依赖注入到两个组件中,在一个组件中设置其值并在其他组件中检索。

        === 更新==

        可以使用 skipLocationChange 选项

        customers.component.ts

        this.router.navigateByUrl("/customers/details/1",{skipLocationChange:true});
        

        在 details 组件中,如下所示检索它

        selectedCustId:string=""
        
            ngOnInit() {
            this.route.paramMap.subscribe((params:ParamMap)=>this.selectedCustId=params.get('id'))
              }
        

        【讨论】:

        • 我发现仅仅为此创建一个服务很麻烦。当然,如果我没有找到任何其他解决方案,我会这样做。默认情况下不处理这么简单的事情似乎很可惜。
        【解决方案4】:

        如您所说,每条路线中的 data 键都可以解决您的问题。

        总而言之,路由就像一棵巨大的树,通过 snapshot 键可以用作可观察的或直接的原始数据。

        举个例子

        主组件

        ngOnInit() {
            this.route.data.subscribe((data: any )=> {
              data.test = 'wassup';
        
            })
          }
        

        子组件

        ngOnInit() {
                this.route.parent.data.subscribe((data: any )=> {
                    console.log(data);      
                })
        /* or console.log(this.route.parent.snapshot.data) */
              }
        

        Somewhere组件

        ngOnInit() {
                this.route.root.children[0].data.subscribe((data: any )=> {
                    console.log(data);      
                })
              }
        

        如果您有一个复杂的路由架构,我真的建议您编写一个 readerService 代码,该服务将从根或任何位置进入树内,并为您提供参数的整个映射和所有想要的数据。

        【讨论】:

          【解决方案5】:

          你必须从@angular/router 导入RouterModule 和Routes。

              import { RouterModule, Routes } from '@angular/router';
          
              const routes: Routes = [{
                path: 'login/:stateToRedirect',
                component: LoginComponent,
                data: { 'yourParam': 'here goes your param' }
              }]
          

          在你的组件中 例如:

              import { ActivatedRoute, ParamMap } from '@angular/router';
          
              @Component({})...
              export class LoginComponent(){
                 constructor(private route: ActivatedRoute){}
                 private someFunction(){
                    this.route.data.subscribe((data: any) => {
                      console.log(data.yourParam);
                    }); 
                 }
          

          你可以像这样传递静态参数而不显示在url上

          【讨论】:

          • 但是这样做,参数会出现在URL中?
          • 你能像这样传递参数,然后路由器使用 this.router.navigate(['/', { skipLocationChange: true }]; ??
          猜你喜欢
          • 1970-01-01
          • 2017-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-22
          • 2017-07-16
          相关资源
          最近更新 更多