【问题标题】:Angular 2 - How to pass URL parameters?Angular 2 - 如何传递 URL 参数?
【发布时间】:2017-02-12 23:36:50
【问题描述】:

我在 Angular 2 中创建了一个单页抵押计算器应用程序,它对我来说就像一个学习游乐场(试图更习惯当前工作中使用的技术堆栈)...如果你愿意,它在 http://www.mortgagecalculator123.com 运行看看它。如果您想查看它,我已经在页面上使用 Fork Me 链接将其开源。

无论如何,我想做的是能够直接从 URL 将变量传递给我的应用程序,以便我的 Angular 2 应用程序可以使用它们。像这样的东西:http://www.mortgagecalculator123.com/?var1=ABC&var2=DEF

我尝试过以下操作,在我的 app.component.ts 中,我添加了以下内容:

import { Router, ActivatedRoute, Params } from '@angular/router';

AppComponent {
private var1: string;
private var2: string;

constructor(
  private route: ActivatedRoute,
  private router: Router
  ) {}

ngOnInit() {
  this.route.params.forEach((params: Params) => {
      this.var1 = params['var1'];
      this.var2 = params['var2'];
  });

  console.log(this.var1, this.var2);
}
...
}

但这不起作用,当我运行 npm start 时,我收到以下错误:

aot/app/app.component.ngfactory.ts(45,30):错误 TS2346:提供的参数与调用目标的任何签名都不匹配。

谢谢你,任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js angular npm


    【解决方案1】:

    我创建了一个使用查询参数工作的拉取请求。我会尽力解释我所做的一切。

    前面的答案不起作用的原因是因为您根本没有使用路由器。您创建了一个没有路由的大型应用程序组件。为了解决我们需要开始使用路由模块的问题,我还建议您阅读以下两个教程:RoutingRouting & Navigation

    首先我们需要更改您的index.html,将其添加到您的<head>

    <base href="/">
    

    请参阅 here 为什么添加它很重要。

    那么,既然您正在使用您的 AppComponent 来显示我们创建新组件所需的一切,我们将其称为 RootComponent。在您的index.html 上将&lt;my-app&gt; 更改为&lt;root&gt;;它看起来像这样:

    <root>Loading...</root>
    

    现在在您的app 文件夹中,我们需要创建两个文件,第一个是root.component.ts,如下所示:

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'root',
      template: `<router-outlet></router-outlet>`,
    })
    export class RootComponent {
      constructor() {  }
    }
    

    看看我们有&lt;router-outlet&gt;&lt;/router-outlet&gt;作为模板,Angular会根据路由注入我们的组件。

    我们还需要再创建一个文件,即main.route.ts,它是这个样子的:

    import { Routes, RouterModule }   from '@angular/router';
    import { AppComponent } from './app.component';
    
    export const mainRoutes: Routes = [
      { path: '', component: AppComponent }
    ];
    export const mainRoutingProviders: any[] = [];
    export const routing = RouterModule.forRoot(mainRoutes);
    

    在这个文件中,我们说对于我们的基本路由,我们要渲染我们的AppComponent

    我们已经创建了新文件,现在我们需要在您的app.module.ts 中告诉我们的App Module,以便我们导入新文件并声明新组件。我们还需要更改我们的 boostrap 组件:

    import {NgModule}      from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import {FormsModule, ReactiveFormsModule} from "@angular/forms";
    import {AppComponent}  from './app.component';
    import {RootComponent}  from './root.component'; // we import our new RootComponent
    import {ChartModule} from 'primeng/primeng';
    import {TooltipModule} from 'primeng/primeng';
    import { routing, mainRoutingProviders } from './main.routes'; // We also import our Routes
    
    @NgModule({
      imports: [
        BrowserModule,
        ChartModule,
        FormsModule,
        mainRoutingProviders, // we also need to import our route provider into the module
        ReactiveFormsModule,
        routing, // and also import our routes declarations
        TooltipModule
      ],
      declarations: [AppComponent, RootComponent], // we declare our new RootCpmponent
      bootstrap: [RootComponent] // Notice that we are now using our RootComponent to bootstrap our app
    })
    export class AppModule {
    }
    

    现在一切就绪,我们现在终于可以开始向我们的应用程序传递参数了,在您的 AppComponent 上导入 RouterActivatedRoute 和来自 @angular/routerParams,这样您的 AppComponent 将看起来像这样:

    import { Component, OnDestroy, OnInit } from '@angular/core';
    import { Router, ActivatedRoute, Params } from '@angular/router';
    import { Subscription } from 'rxjs/Subscription';
    
    export class AppComponent implements OnInit, OnDestroy {
      private var1: string;
      private var2: string;
      private sub: Subscription;
    
      constructor(
        private route: ActivatedRoute,
        private router: Router
      ) {}
    
      ngOnInit() {
        // assign the subscription to a variable so we can unsubscribe to prevent memory leaks
        this.sub = this.route.queryParams.subscribe((params: Params) => {
          this.var1 = params['var1'];
          this.var2 = params['var2'];
          console.log(this.var1, this.var2);
        });
      }
    
      ngOnDestroy() {
        this.sub.unsubscribe();
      }
    ...
    }
    

    你可以看到拉取请求here

    【讨论】:

    • 法比奥,这正是我一直试图弄清楚的。太感谢了。谈到 Angular 2,我还是个新手,非常感谢您花费宝贵的时间来解释一切。它不仅现在有效,而且按照您概述的逻辑,它一直是一个很好的学习练习。声望50分当之无愧。
    • 还有一个问题......在 app.component.ts 中,是否需要在第 65 行保留:'私有路由器:路由器'?看起来这是一个未使用的参数 no?
    • 真的,你不需要那个。除非你最终打算重定向到某个路线。
    • 已解决,谢谢。问题是我定义了一个路由,path: '' 重定向到我的组件,该组件的路径为mycomponent。如果我启动 http:\\myapp\?myVar=AAA 我没有得到任何变量。但是如果我启动 http:\\myapp\mycomponent?myVar=AAA 我可以从 url 中检索参数。
    • 这很有帮助。请注意,Angular 不鼓励使用 queryParams,您应该改用 queryParamMap。您可以通过params['params']['var1']angular.io/guide/router#activated-route访问参数
    【解决方案2】:

    您似乎正在处理 Queryparams 。所以要访问它们,你可以试试下面的代码,

    this.var1= this.route
          .queryParams
          .map(params => params['var1']);
    

    【讨论】:

    • 当我这样做时,我收到以下错误:aot/app/app.component.ngfactory.ts(45,30):错误 TS2346:提供的参数与调用目标的任何签名都不匹配。 app/app.component.ts(90,39): 错误 TS2339: 属性 'map' 不存在于类型 'Observable'。
    • 我试过用:import 'rxjs/add/operator/map';但后来我回到原来的错误 TS2346:提供的参数与调用目标的任何签名都不匹配。疯狂地传递变量这样简单的事情怎么会如此复杂......
    • 感谢您的尝试,希望其他人可以提供帮助。
    • 仅供参考,queryParams 已被替换为 queryParamsMapSource
    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 2017-02-24
    • 2017-05-12
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 2017-06-10
    • 2017-04-21
    相关资源
    最近更新 更多