2016-04-21 124 views
2

我正在使用一個角度的應用程序,它使用鏈接到多個組件AppComponent的路由器。這裏是plunker一個簡化版本來說明問題(因爲某些原因,完全相同的代碼在本地而不是運行在plunker。)Angular 2:ngOnInit被稱爲嘗試呈現模板時,從url開始使用id

當應用程序從http://localhost:3000http://localhost:3000/home,鏈接fruit1fruit2工作正常(點擊開始導致URL更改爲http://localhost:3000/fruit/1與描述文本)。然而,問題是,當這個URL http://localhost:3000/fruit/1(鍵入這個URL並按回車鍵)開始時,似乎fruit-detail.component.tsngOnInit內的服務調用被稱爲AFTER試圖呈現其html組件,這導致下面的堆棧跟蹤:

EXCEPTION: TypeError: Cannot read property 'description' of null in [ desc: {{fruit.description}} in [email protected]:6] 
angular2.dev.js:23925 EXCEPTION: TypeError: Cannot read property 'description' of null in [ desc: {{fruit.description}} in [email protected]:6]BrowserDomAdapter.logError @ angular2.dev.js:23925BrowserDomAdapter.logGroup @ angular2.dev.js:23936ExceptionHandler.call @ angular2.dev.js:1320(anonymous function) @ angular2.dev.js:12857schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ angular2.dev.js:13666NgZoneImpl.inner.inner.fork.onHandleError @ angular2.dev.js:2143ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runGuarded @ angular2-polyfills.js:300NgZoneImpl.runInner @ angular2.dev.js:2155NgZone.run @ angular2.dev.js:13749(anonymous function) @ angular2.dev.js:12956schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._checkStable @ angular2.dev.js:13689NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.setMicrotask @ angular2.dev.js:13660NgZoneImpl.inner.inner.fork.onHasTask @ angular2.dev.js:2135ZoneDelegate.hasTask @ angular2-polyfills.js:449ZoneDelegate._updateTaskCount @ angular2-polyfills.js:466ZoneDelegate.invokeTask @ angular2-polyfills.js:427Zone.runTask @ angular2-polyfills.js:320drainMicroTaskQueue @ angular2-polyfills.js:541ZoneTask.invoke @ angular2-polyfills.js:493 
angular2.dev.js:23925 ORIGINAL EXCEPTION: TypeError: Cannot read property 'description' of nullBrowserDomAdapter.logError @ angular2.dev.js:23925ExceptionHandler.call @ angular2.dev.js:1329(anonymous function) @ angular2.dev.js:12857schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ angular2.dev.js:13666NgZoneImpl.inner.inner.fork.onHandleError @ angular2.dev.js:2143ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runGuarded @ angular2-polyfills.js:300NgZoneImpl.runInner @ angular2.dev.js:2155NgZone.run @ angular2.dev.js:13749(anonymous function) @ angular2.dev.js:12956schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._checkStable @ angular2.dev.js:13689NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.setMicrotask @ angular2.dev.js:13660NgZoneImpl.inner.inner.fork.onHasTask @ angular2.dev.js:2135ZoneDelegate.hasTask @ angular2-polyfills.js:449ZoneDelegate._updateTaskCount @ angular2-polyfills.js:466ZoneDelegate.invokeTask @ angular2-polyfills.js:427Zone.runTask @ angular2-polyfills.js:320drainMicroTaskQueue @ angular2-polyfills.js:541ZoneTask.invoke @ angular2-polyfills.js:493 
angular2.dev.js:23925 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23925ExceptionHandler.call @ angular2.dev.js:1332(anonymous function) @ angular2.dev.js:12857schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ angular2.dev.js:13666NgZoneImpl.inner.inner.fork.onHandleError @ angular2.dev.js:2143ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runGuarded @ angular2-polyfills.js:300NgZoneImpl.runInner @ angular2.dev.js:2155NgZone.run @ angular2.dev.js:13749(anonymous function) @ angular2.dev.js:12956schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._checkStable @ angular2.dev.js:13689NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.setMicrotask @ angular2.dev.js:13660NgZoneImpl.inner.inner.fork.onHasTask @ angular2.dev.js:2135ZoneDelegate.hasTask @ angular2-polyfills.js:449ZoneDelegate._updateTaskCount @ angular2-polyfills.js:466ZoneDelegate.invokeTask @ angular2-polyfills.js:427Zone.runTask @ angular2-polyfills.js:320drainMicroTaskQueue @ angular2-polyfills.js:541ZoneTask.invoke @ angular2-polyfills.js:493 
angular2.dev.js:23925 TypeError: Cannot read property 'description' of null 
    at AbstractChangeDetector.ChangeDetector_FruitDetailComponent_0.detectChangesInRecordsInternal (viewFactory_FruitDetailComponent:30) 
    at AbstractChangeDetector.detectChangesInRecords (angular2.dev.js:9689) 
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9672) 
    at AbstractChangeDetector._detectChangesInViewChildren (angular2.dev.js:9751) 
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9676) 
    at AbstractChangeDetector._detectChangesContentChildren (angular2.dev.js:9745) 
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9673) 
    at AbstractChangeDetector._detectChangesInViewChildren (angular2.dev.js:9751) 
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:9676) 
    at AbstractChangeDetector.detectChanges (angular2.dev.js:9661) 

然後,這是記錄到控制檯,這就是爲什麼我懷疑ngOnInit後調用。那麼,即使直接從'水果/ 1'網址直接加載,如何有一個工作的應用程序?任何幫助表示讚賞!謝謝!

===== extract data called!! 
fruit-detail.component.ts:25 got fruit inside fruitComponent !apple 

回答

2

您可以使用Elvis操作符此:

<h2> desc: {{fruit?.description}} </h2> 

事實上,呼叫this._foodService.getData()異步執行,你會得到ngOnInit方法返回後的結果。

由於您使用路由,我認爲OnActivate接口和它的routerOnActivate方法是您正在尋找。如果您在此方法中返回承諾,則組件將在更改路由之前等待承諾解決。所以當組件顯示時,數據會在那裏,你不會有這樣的問題。

這裏有一個例子:

@Component({ 
    (...) 
}) 
export class FruitDetailComponent implements OnInit, OnActivate { 
    fruit = null; 

    constructor(
    private _rbacService: FoodService, 
    private _routeParams: RouteParams) {} 

    routerOnActivate(next: ComponentInstruction, 
        prev: ComponentInstruction) { 
    return new Promise(resolve => { 
     let id = +this._routeParams.get('id'); 
     console.log('on init fruit component: id = '+id); 
     //get read write roles 
     this._rbacService.getData().subscribe(data =>{ 
     this.fruit = data['fruits'].filter(obj => obj.id === id)[0]; 
     console.log('got fruit inside fruitComponent '+this.fruit.description); 
     resolve(null); 
     }) 
    }); 
    } 
} 

請參閱此鏈接瞭解詳情:

+0

感謝您的答覆!有趣的是,使用第二個選項('OnActivate')不起作用;仍然有同樣的錯誤。但是貓王操作員可以做到這一點!那麼,對於elvis算子來說,事實上,最初被評估爲null的變量會在以後再次被評估嗎?有沒有辦法在模板內的任何地方打開「貓王模式」?這是一個拖動不得不添加'?'在每個變量之後。謝謝! – totoro

+0

事實上,你可以從'onActivate'方法返回一個承諾,這裏是超級有用的部分。 – jcroll

相關問題