Tôi có một dự án angular2 như sau:Angular2 mẫu cố gắng để render giá trị trước khi giá trị trả về từ http.get
package.json:
{
"name": "self-assessment",
"version": "1.0.0",
"scripts": {
"postinstall": "npm run typings install",
"lite": "lite-server",
"gulp": "gulp",
"start": "concurrent \"npm run gulp\" \"npm run lite\" ",
"typings" : "typings"
},
"license": "ISC",
"dependencies": {
"angular2": "2.0.0-beta.3",
"systemjs": "0.19.6",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.0",
"zone.js": "0.5.11"
},
"devDependencies": {
"autoprefixer": "^6.2.1",
"cssnano": "^3.4.0",
"concurrently": "^1.0.0",
"gulp": "^3.9.0",
"gulp-ext-replace": "^0.2.0",
"gulp-imagemin": "^2.4.0",
"gulp-postcss": "^6.0.1",
"gulp-sourcemaps": "^1.6.0",
"gulp-typescript": "^2.10.0",
"gulp-uglify": "^1.5.1",
"lite-server": "^2.0.1",
"postcss": "^5.0.13",
"postcss-scss": "^0.1.3",
"precss": "^1.3.0",
"typings":"^0.6.8",
"tsd": "^0.6.5-beta"
}
}
app.component.ts:
import {Component} from 'angular2/core';
import {AssessmentListComponent} from "./assessment-list.component";
import {HomeComponent} from "./home.component";
import {ApiService} from "../services/api.service";
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from 'angular2/router';
import {AssessmentComponent} from "./assessment.component";
@Component({
selector: 'my-app',
templateUrl: 'app/components/app.component.html',
directives: [
ROUTER_DIRECTIVES,
],
providers: [
ApiService,
ROUTER_PROVIDERS,
]
})
@RouteConfig([
{path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true},
{path: '/assessments', name: 'Assessments', component: AssessmentListComponent},
{path: '/assessment/:id', name: 'Assessment', component: AssessmentComponent},
])
export class AppComponent {
title = "Welcome to Self-Assessment"
}
assessment.component.ts:
import {Component, OnInit} from 'angular2/core';
import {AssessmentModel} from '../models/assessment.model';
import {RouteParams} from 'angular2/router';
import {ApiService} from '../services/api.service';
@Component({
selector: 'assessment-component',
templateUrl: 'app/components/assessment.component.html',
})
export class AssessmentComponent implements OnInit{
assessment: AssessmentModel;
errorMessage: any;
constructor(
private _apiService: ApiService,
private _routeParams: RouteParams
) {}
ngOnInit():any {
let id = +this._routeParams.get('id');
this.getAssessment(id);
}
private getAssessment(id: number) {
this._apiService.getAssessment(id)
.subscribe(
assessment => this.assessment = assessment,
error => this.errorMessage = <any>error
);
}
goBack() {
console.log(this.assessment);
}
}
api.service.ts:
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class ApiService {
constructor(private _http: Http) {}
private _baseApiUrl = 'http://localhost:8000/';
getAssessments() {
return this.getObjectList('assessments', 'json');
}
getAssessment(id: number) {
return this.getObject('assessments', id, 'json');
}
getObjectList(listName:string, listExtension: string) {
var url = this._baseApiUrl + listName + '.' + listExtension;
return this._http.get(url)
.map(response => response.json())
.catch(this.handleError);
}
getObject(objectName:string, objectId:number, objectExtension: string) {
var url = this._baseApiUrl + objectName + '/' + objectId + '.' + objectExtension;
return this._http.get(url)
.map(response => response.json())
.catch(this.handleError);
}
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
và cuối cùng assessment.component.html:
<h3>{{ assessment.id }}</h3>
<button (click)="goBack()">Go Back 2</button>
Khi trang web được gọi với url: http://localhost:3000/assessment/4 nó thực hiện các cuộc gọi thích hợp cho back2 end hai lần và tạo ra các lỗi sau đây trong bảng điều khiển
Uncaught EXCEPTION: TypeError: Cannot read property 'id' of undefined in [{{ assessment.id }} in [email protected]:4]
ORIGINAL EXCEPTION: TypeError: Cannot read property 'id' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'id' of undefined
at AbstractChangeDetector.ChangeDetector_AssessmentComponent_0.detectChangesInRecordsInternal (viewFactory_AssessmentComponent:30:28)
at AbstractChangeDetector.detectChangesInRecords (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8116:14)
at AbstractChangeDetector.runDetectChanges (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8099:12)
at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8184:14)
at AbstractChangeDetector.runDetectChanges (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8103:12)
at AbstractChangeDetector._detectChangesContentChildren (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8178:14)
at AbstractChangeDetector.runDetectChanges (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8100:12)
at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8184:14)
at AbstractChangeDetector.runDetectChanges (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8103:12)
at AbstractChangeDetector.detectChanges (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8088:12)
ERROR CONTEXT:
[object Object]ExceptionHandler.call @ angular2.dev.js:1206(anonymous function) @ angular2.dev.js:12591NgZone._notifyOnError @ angular2.dev.js:13635collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:13539Zone.run @ angular2-polyfills.js:1247NgZone._notifyOnTurnDone @ angular2.dev.js:13450(anonymous function) @ angular2.dev.js:13565zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
Vì vậy, nó có vẻ như thể {{}} assessment.id đang cố gắng để render trước khi đối tượng được trả về từ back-end. Nếu tôi sau đó nhấn vào nút "Go Back 2" nút nó sẽ an ủi đăng đối tượng thích hợp:.
{"id":4,"title":"Assessment Title here!","description":"Here is a description","questions":["http://localhost:8000/questions/1.json","http://localhost:8000/questions/2.json","http://localhost:8000/questions/3.json","http://localhost:8000/questions/4.json","http://localhost:8000/questions/5.json","http://localhost:8000/questions/6.json","http://localhost:8000/questions/7.json","http://localhost:8000/questions/8.json","http://localhost:8000/questions/9.json","http://localhost:8000/questions/10.json","http://localhost:8000/questions/11.json","http://localhost:8000/questions/12.json","http://localhost:8000/questions/13.json"],"responses":[]}
"Điều thú vị là" Tôi không nhìn thấy vấn đề ở những nơi khác trong ứng dụng (ví dụ có thể tải và hiển thị assessment- danh sách tốt, vv). Ngoài ra, tôi có cùng một vấn đề trong một ứng dụng Ionic2 tôi đã làm việc với đêm qua như một dự án học tập.
Đã googled mông của tôi ra, hy vọng ai đó biết câu trả lời cho câu đố này.
Cảm ơn!
Thử '{{assessment? .id}}' '- [toán tử Elvis] (https://angular.io/docs/ts/latest/guide/template-syntax.html#!#expression-operators). Bạn có thể không có vấn đề với danh sách vì 'NgFor' xử lý trường hợp mảng không xác định hoặc trống cho bạn. Sau đó, khi dữ liệu xuất hiện, 'NgFor' được đánh giá lại. –
Điều đó có hiệu quả, cảm ơn bạn. Đó là một cách 'đúng' để giải quyết nó hay là có một giải pháp thích hợp hơn? Nó có vẻ kỳ lạ mà sẽ không được đề cập trong bất kỳ hướng dẫn và như vậy tôi đã nhìn vào (mà tôi đã nhận thấy anyway). Cảm ơn @MarkRajcok! – Gerald
Xem câu trả lời của tôi. Nhiều hướng dẫn thích hiển thị các ví dụ với các danh sách, đó có lẽ là lý do tại sao toán tử Elvis thường không được các nhà phát triển học hỏi về Góc. (Câu hỏi này xuất hiện thường xuyên trên SO.) –