我是角度2的初学者,我正在建立我的第一个应用程序,同时遵循Pluralsight课程。 我正在使用TypeScript。 我有一个特定的组件(名为:property-detail.component.ts),我在其中尝试从服务(property.service.ts)引用指令。 我正在根模块中注册服务,并使用" contructor"将服务注入到组件中。方法。 在一个组件(property-list.component.ts)中,我调用产品列表,这很好。 然后我尝试在(property-detail.component.ts)中调用相同的服务,其中我只想显示单个属性的详细信息,但是当我运行应用程序时,我收到以下错误
错误消息
{node_modules/@angular/core/bundles/core.umd.js:3462 EXCEPTION: Uncaught (in promise): Error: Error in app/property/property-detail.component.html:9:42 caused by: Cannot read property 'propertyName' of undefined
TypeError: Cannot read property 'propertyName' of undefined
at _View_PropertyDetailComponent0.detectChangesInternal (PropertyDetailComponent.ngfactory.js:284:62)}
我正在为整个应用程序使用单个应用程序模块(app.module.ts)来为自己简化它。
以下是组件和模块:
app.module.ts
import { NgModule } from '@angular/core';
//brownermodule exposes the ngIg and ngFor directive
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { PropertyListComponent } from "./property/property-list.component";
import { PropertyCityFilterPipe } from "./property/property-cityfilter.pipe";
import { StarComponent } from "./shared/star.component";
import { PropertyDetailGuard } from "./property/property-guard.service";
import { PropertyDetailComponent } from "./property/property-detail.component";
import { WelcomeComponent } from "./home/welcome.component";
import { PropertyService } from "./property/property.service";
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([
{ path: 'property', component: PropertyListComponent },
{ path: 'property/:id',
canActivate: [PropertyDetailGuard],
component: PropertyDetailComponent
},
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
])
],
declarations: [
AppComponent,
PropertyListComponent,
PropertyCityFilterPipe,
StarComponent,
PropertyDetailComponent,
WelcomeComponent,
],
providers: [PropertyDetailGuard, PropertyService],
bootstrap: [ AppComponent ]
})
export class AppModule { }
property.service.ts
import { Injectable, } from "@angular/core";
//import { IProperty } from "./property";
import { Http, Response } from "@angular/http";
import { Observable } from "rxjs/Observable";
import "rxjs/add/operator/catch";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";
import { IProperty } from "./property";
@Injectable()
export class PropertyService {
private _propertyUrl = 'api/property/property.json';
constructor(private _http: Http) { }
getPropertys(): Observable<IProperty[]> {
return this._http.get(this._propertyUrl)
.map((response: Response) => <IProperty[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
getProperty(id: number): Observable<IProperty> {
return this.getPropertys()
.map((property: IProperty[]) => property.find(p => p.propertyId === id));
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
属性-list.component.ts
import { Component, OnInit } from "@angular/core";
import { IProperty } from "./property";
import { PropertyService } from "./property.service";
@Component({
moduleId: module.id,
templateUrl: 'property-list.component.html',
styleUrls: ['property-list.component.css']
})
export class PropertyListComponent implements OnInit {
pageTitle: string = 'Rental Listings';
imageWidth: number = 120;
imageMargin: number = 2;
listFilter: string;
errorMessage: string;
property: IProperty[];
constructor(private _propertyService: PropertyService) {
}
ngOnInit(): void {
this._propertyService.getPropertys()
.subscribe(property => this.property = property,
error => this.errorMessage = <any>error);
}
onRatingClicked(message: string): void {
this.pageTitle = "Property: " + message;
}
}
属性-detail.component.ts
import { Component, OnInit, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { Subscription } from "rxjs/Subscription";
import { IProperty } from "./property";
import { PropertyService } from "./property.service";
@Component({
templateUrl: 'app/property/property-detail.component.html'
})
export class PropertyDetailComponent implements OnInit, OnDestroy {
pageTitle: string = 'Property Detail';
property: IProperty;
errorMessage: string;
private sub: Subscription;
constructor(private _route: ActivatedRoute,
private _router: Router,
private _propertyService: PropertyService) {
}
ngOnInit(): void {
this.sub = this._route.params.subscribe(
params => {
let id = +params['id'];
this.getProperty(id);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
getProperty(id: number) {
this._propertyService.getProperty(id).subscribe(
property => this.property = property,
error => this.errorMessage = <any>error);
}
onBack(): void {
this._router.navigate(['/property']);
}
onRatingClicked(message: string): void {
this.pageTitle = 'Property Detail: ' + message;
}
}
property-detail.component.html(你会看到我只插入了一个指令 - {{property.propertyName}}来简化事情
<div class='panel panel-primary'>
<div class='panel-heading' style='font-size:large'>
{{pageTitle}}
</div>
<div class='panel-body'>
<div class='row'>
<div class='col-md-6'>
<div class='row'>
<div class='col-md-3'>Name:</div>
<div class='col-md-6'>{{property.propertyName}}</div>
</div>
<div class='row'>
<div class='col-md-3'>Code:</div>
<div class='col-md-6'></div>
</div>
<div class='row'>
<div class='col-md-3'>Description:</div>
<div class='col-md-6'></div>
</div>
<div class='row'>
<div class='col-md-3'>Availability:</div>
<div class='col-md-6'></div>
</div>
<div class='row'>
<div class='col-md-3'>Price:</div>
<div class='col-md-6'></div>
</div>
<div class='row'>
<div class='col-md-3'>5 Star Rating:</div>
<div class='col-md-6'>
<!--<cx-star [rating]='property.starRating'
(ratingClicked)='onRatingClicked($event)'>
</cx-star>-->
</div>
</div>
</div>
<!--<div class='col-md-6'>
<img class='center-block img-responsive'
[style.width.px]='200'
[style.margin.px]='2'
[src]='property.imageUrl'
[title]='property.productName'>
</div>-->
</div>
</div>
<div class='panel-footer'>
<a class='btn btn-default' (click)='onBack()' style='width:80px'>
<i class='glyphicon glyphicon-chevron-left'></i> Back
</a>
</div>
</div>
对此方面的任何帮助都将受到高度赞赏
答案 0 :(得分:0)
把* ngIf =&#34;属性&#34;在标签{{property.propertyName}}内部,在订阅者返回值之前以及渲染时模板property.propertyName未定义 - alehn96 14小时前