0

我正在关注https://angular.io/start/routing上的 Angular 教程。但是,经过某个步骤后,我的浏览器会显示一个空白页面并 Error: Can't resolve all parameters for ProductDetailsComponent: (?)在控制台中给我。

我尝试了不同的浏览器(默认使用 Firefox),并评论/玩弄代码以查看导致错误的确切行(private route: ActivateRoute在 product-details.component.ts 的构造函数中)。还检查了拼写错误/我是否确实错过了教程中的某些内容,但据我所知,我已将其 100% 遵循。

我还将 Ubuntu Mate 19.04 与 IntelliJ IDEA 一起使用。

产品详细信息.component.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { products } from '../products';

export class ProductDetailsComponent implements OnInit {
  product;

  constructor(
    private route: ActivatedRoute,
  ) { }
}

ngOnInit() {
  this.route.paramMap.subscribe(params => {
    this.product = products[+params.get('productId')];
  });
}
}

产品详细信息.component.html:

<h2>Product Details</h2>
<div *ngIf="product">
  <h3>{{ product.name }}</h3>
  <h4>{{ product.price | currency }}</h4>
  <p>{{ product.description }}</p>    
</div>

产品列表.component.ts:

import { Component } from '@angular/core';

import { products } from '../products';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent {
  products = products;

  share() {
    window.alert('The product has been shared!');
  }

  onNotify() {
    window.alert('You will be notified when the product goes on sale');
  }
}

产品列表.component.html:

<h2>Products</h2>

<div *ngFor="let product of products; index as productId">

  <h3>
    <a [title]="product.name + ' details'" [routerLink]="['/products', productId]">
      {{ product.name }}
    </a>
  </h3>

  <p *ngIf="product.description">
    Description: {{ product.description }}
  </p>

  <button (click)="share()">
    Share
  </button>

  <app-product-alerts
    [product]="product"
    (notify)="onNotify()">
  </app-product-alerts>

</div>

app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
import { ProductDetailsComponent } from './product-details/product-details.component';

@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
    ])
  ],
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent,
    ProductDetailsComponent,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

产品.ts:

export const products = [
  {
    name: 'Phone XL',
    price: 799,
    description: 'A large phone with one of the best screens'
  },
  {
    name: 'Phone Mini',
    price: 699,
    description: 'A great phone with one of the best cameras'
  },
  {
    name: 'Phone Standard',
    price: 299,
    description: ''
  }
];

本教程中预期的结果是路由将我从主视图重定向到特定产品的视图,但是在添加上述行之后,该站点仅显示一个空白页面。

4

5 回答 5

1
product-details.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { products } from '../products';

@Component({
  selector: 'app-product-details',
  templateUrl: './product-details.component.html',
  styleUrls: ['./product-details.component.css']
})
export class ProductDetailsComponent implements OnInit {
  product;

  constructor(
    private route: ActivatedRoute,
  ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(params => {
      this.product = products[+params.get('productId')];
    });
  }
}

product-list.component.ts

import { Component } from '@angular/core';

import { products } from '../products';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent {
  products = products;

  share() {
    window.alert('The product has been shared!');
  }

  onNotify() {
    window.alert('You will be notified when the product goes on sale');
  }
}
App.module.ts

import { BrowserModule } from '@angular/platform-browser';

import { NgModule } from '@angular/core';

import { RouterModule, Routes } from '@angular/router';

import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';

import { ProductDetailsComponent } from './product-details/product-details.component';

import { ProductListComponent } from './product-list/product-list.component';

@NgModule({
  declarations: [
    AppComponent,
    ProductDetailsComponent,
    ProductListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
    ])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
于 2019-07-22T14:08:24.617 回答
0

从'../products'导入{产品};

您从哪里获得数据产品模型。它来自 REST API 吗?

你能告诉我们你的 services.ts 和 product.ts 代码吗?

如果您从 REST API 获取产品数据。将该产品模型存储到 observable 中并在 ProductDetailsComponent 中订阅该产品模型。

如果您使用多个服务,请确保两个服务不相互依赖。

于 2019-07-22T13:27:37.080 回答
0

根据您的代码:ngOnInit()方法写在外部ProductDetailsComponent,如下更新

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { products } from '../products';

export class ProductDetailsComponent implements OnInit {
  product;

  constructor(
    private route: ActivatedRoute,
  ) { }


ngOnInit() {
  this.route.paramMap.subscribe(params => {
    this.product = products[+params.get('productId')];
  });
 }
}
于 2019-07-22T13:48:59.487 回答
0

通过更新包依赖项使其工作(参见https://github.com/lena-spb/untitled4):

包.json

"dependencies": {
    "rxjs": "6.5.2",
    "tslib": "1.10.0",
    "core-js": "2.6.9",
    "zone.js": "0.9.1",
    "jasmine-core": "2.99.1",
    "@angular/core": "8.1.2",
    "@angular/forms": "8.1.2",
    "@angular/common": "8.1.2",
    "@angular/router": "8.1.2",
    "jasmine-marbles": "0.6.0",
    "@angular/compiler": "8.1.2",
    "web-animations-js": "2.3.2",
    "@angular/animations": "8.1.2",
    "@angular/platform-browser": "8.1.2",
    "angular-in-memory-web-api": "0.8.0",
    "@angular/platform-browser-dynamic": "8.1.2"
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.801.2",
    "@angular/cli": "~8.1.2",
    "@angular/compiler-cli": "~8.1.2",
    "@angular/language-service": "~8.1.2",
    "@types/node": "~8.9.4",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "~4.5.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~3.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.4.0",
    "ts-node": "~8.3.0",
    "tslint": "~5.11.0",
    "typescript": "3.4.5"
  }

src/app/app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {RouterModule, Routes} from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
import { ProductDetailesComponent } from './product-detailes/product-detailes.component';

const appRoutes: Routes = [
  { path: '', component: ProductListComponent },
  { path: 'products/:productId', component: ProductDetailesComponent }
];

@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
  ],
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent,
    ProductDetailesComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

src/app/product-detailes/product-detailes.component.ts

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, ParamMap} from '@angular/router';
import { products } from '../products';

@Component({
  selector: 'app-product-detailes',
  templateUrl: './product-detailes.component.html',
  styleUrls: ['./product-detailes.component.css']
})
export class ProductDetailesComponent implements OnInit {
  product;

  constructor(
    private route: ActivatedRoute,
  ) { }

  ngOnInit() {
    this.route.paramMap.subscribe((params: ParamMap) => {
      this.product = products[+params.get('productId')];
    });
  }
}

于 2019-07-22T13:48:06.807 回答
0

让它工作:

ngOnInit() {
    this.route.paramMap.subscribe((params: ParamMap) => {
      let productId = params.get('productId') || 0;
        this.product = products[productId] || null;
    });
  }
于 2021-09-19T13:41:23.843 回答