2017-03-09 12 views
11

मुझे अंगुलर 2 रूटिंग के साथ एक बहुत ही अजीब समस्या है जहां मैं ngOnInit उस घटक में हूं जहां मैं रूटिंग कर रहा हूं उसे दो बार बुलाया जा रहा है, और ब्राउज़र में मार्ग रीसेट हो रहा है मूल मार्गकोणीय 2 रूटिंग समस्या और ngOnInit को दो बार बुलाया गया

मेरे पास NotificationListComponent और में NotificationEditComponent है।

मेरी रूट AppModule में, मैंने RouterModule को किसी भी अप्रयुक्त मार्ग को /maintenance/list पर रीडायरेक्ट करने के लिए सेट किया है।

app.module.ts:

@NgModule({ 
    declarations: [ 
    AppComponent 
    ], 
    imports: [ 
    BrowserModule, 
    HttpModule, 
    RouterModule.forRoot([ 
     {path: "", redirectTo: "maintenance/list", pathMatch: "full"}, 
     {path: "**", redirectTo: "maintenance/list", pathMatch: "full"} 
    ], {useHash: true}), 
    CoreModule.forRoot({notificationUrl: "http://localhost:8080/notification-service/notifications"}), 
    MaintenanceModule 
    ], 
    providers: [NotificationService], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

और मैं जो बताते हैं /maintenance/list मार्ग मेरी MaintenanceModule में परिभाषित किया गया है, मेरे NotificationListComponent पर है, साथ ही एक /maintenance/edit/:id मार्ग जो मेरे NotificationEditComponent में बताते है।

maintenance.module.ts:

@NgModule({ 
    imports: [ 
    CommonModule, 
    RouterModule.forChild([ 
     {path: "maintenance/list", component: NotificationListComponent, pathMatch: 'full'}, 
     {path: "maintenance/edit/:id", component: NotificationEditComponent, pathMatch: 'full'} 
    ]), 
    FormsModule 
    ], 
    declarations: [ 
    NotificationListComponent, 
    NotificationEditComponent 
    ] 
}) 
export class MaintenanceModule {} 

जब मेरे आवेदन लोड हो जाए, इसे सही ढंग से /maintenance/list मार्ग का अनुसरण करता है, और मैं एक सूची में मेरे सभी सूचनाएं देख सकते हैं।

@Component({ 
    templateUrl: 'notification-list.component.html' 
}) 
export class NotificationListComponent implements OnInit { 

    notifications: Notification[]; 
    errorMessage: string; 

    constructor(private _notificationService: NotificationService, 
       private _router: Router) {} 

    ngOnInit(): void { 
    this._notificationService.getNotifications() 
     .subscribe(
     notifications => this.notifications = notifications, 
     error => this.errorMessage = <any>error); 
    } 

    clearError(): void { 
    this.errorMessage = null; 
    } 
} 

अधिसूचना सूची: सूची में प्रत्येक अधिसूचना के लिए वहाँ एक संपादित करें आइकन है, जो अपनी click घटना मेरी NotificationListComponent

अधिसूचना-list.component.ts में edit(id: number) विधि करने के लिए बाध्य किया गया है .component.html:

<div class="row"> 
    <h1>Notification Maintenance</h1> 

    <div *ngIf="errorMessage" class="alert-box alert"> 
    <span>{{errorMessage}}</span> 
    <a class="right" (click)="clearError()">&times;</a> 
    </div> 

    <p-dataTable [value]="notifications" [sortField]="'code'" [responsive]="true" [sortOrder]="1" [rows]="10" [paginator]="true" [rowsPerPageOptions]="[10,50,100]"> 
    <p-header>Available Notifications</p-header> 
    <p-column [field]="'code'" [header]="'Code'" [sortable]="true" [style]="{'width':'10%'}"></p-column> 
    <p-column [field]="'name'" [header]="'Name'" [sortable]="true" [style]="{'width':'40%'}"></p-column> 
    <p-column [field]="'roles'" [header]="'Roles'" [style]="{'width':'40%'}"></p-column> 
    <p-column [field]="'notificationId'" [header]="'Edit'" [style]="{'width':'10%'}"> 
     <template let-row="rowData" pTemplate="body"> 
     <a [routerLink]="'/maintenance/edit/' + row['notificationId']"><span class="fa fa-pencil fa-2x"></span></a> 
     </template> 
    </p-column> 
    </p-dataTable> 
</div> 

आप देख सकते हैं, edit(id: number) विधि पर नेविगेट करना चाहिए /maintenance/edit/:id मार्ग। जब मैं उस मार्ग पर नेविगेट करने के लिए आइकन पर क्लिक करता हूं, तो ब्राउज़र पता बार में सही मार्ग चमकता है (उदा। localhost:4200/#/maintenance/edit/2), लेकिन फिर पता बार में रूट तुरंत localhost:4200/#/maintenance/list पर बदल जाता है। भले ही मार्ग पता बार में /maintenance/list पर वापस लौटा, मेरा NotificationEditComponent वास्तविक एप्लिकेशन में अभी भी दिखाई दे रहा है। हालांकि, मैं देख सकता हूं कि ngOnInit विधि को मेरे NotificationEditComponent में दो बार बुलाया जा रहा है, क्योंकि id कंसोल पर दो बार लॉग हो जाता है, और यदि मैं ngOnInit फ़ंक्शन में ब्रेकपॉइंट डालता हूं, तो यह उस ब्रेकपॉइंट को दो बार हिट करता है।

अधिसूचना-edit.component.ts:

@Component({ 
    templateUrl: "notification-edit.component.html" 
}) 
export class NotificationEditComponent implements OnInit{ 

    notification: Notification; 
    errorMessage: string; 

    constructor(private _notificationService: NotificationService, 
       private _route: ActivatedRoute, 
       private _router: Router) { 
    } 

    ngOnInit(): void { 
    let id = +this._route.snapshot.params['id']; 
    console.log(id); 
    this._notificationService.getNotification(id) 
     .subscribe(
     notification => this.notification = notification, 
     error => this.errorMessage = <any>error 
    ); 
    } 
} 

यह भी, अन्य समस्याएं उत्पन्न कर सकता है क्योंकि जब उदाहरण [(ngModel)]="notification.notificationId", मूल्य के लिए, मेरे NotificationEditComponent का उपयोग करने में मूल्यों के input मूल्यों बाध्य करने के लिए प्रयास करने से प्रतीत होता है स्क्रीन पर प्रदर्शित नहीं किया जा रहा है, भले ही मैं ऑग्यूरी क्रोम एक्सटेंशन के साथ देख सकूं, साथ ही ऑब्जेक्ट को कंसोल पर लॉग ऑन कर सकूं, कि मान घटक में पॉप्युलेट किया गया है।

अधिसूचना-edit.component।एचटीएमएल:

<div class="row"> 
    <h1>Notification Maintenance</h1> 

    <div *ngIf="errorMessage" class="alert-box alert"> 
    <span>{{errorMessage}}</span> 
    <a class="right" (click)="clearError()">&times;</a> 
    </div> 

    <p-fieldset [legend]="'Edit Notification'"> 
    <label for="notificationId">ID: 
     <input id="notificationId" type="number" disabled [(ngModel)]="notification.notificationId"/> 
    </label> 
    </p-fieldset> 

</div> 

किसी को भी किसी भी विचार क्यों यह हो रहा हो जाएगा है?

अद्यतन:

मैं NotificationService मेरे कॉल हटा दिया है, और उन्हें बस कुछ नकली डेटा के साथ बदल दिया, और फिर रूटिंग काम करना शुरू किया! लेकिन जैसे ही मैं अपनी सेवा में कॉल जोड़ता हूं, मुझे वही समस्या मिलती है जो मैंने ऊपर वर्णित की है। मैंने CoreModule को भी हटा दिया और बस सीधे मेरे MaintenanceModule पर सेवा को जोड़ा, और जब भी मैं नकली डेटा की बजाय वास्तविक सेवा का उपयोग करता हूं तब भी वही समस्या मिलती है।

notification.service.ts:

@Injectable() 
export class NotificationService { 
    private _notificationUrl : string = environment.servicePath; 

    constructor(private _http: Http) { 
    } 

    getNotifications(): Observable<Notification[]> { 
    return this._http.get(this._notificationUrl) 
     .map((response: Response) => <Notification[]>response.json()) 
     .catch(this.handleGetError); 
    } 

    getNotification(id: number): Observable<Notification> { 
    return this._http.get(this._notificationUrl + "/" + id) 
     .map((response: Response) => <Notification>response.json()) 
     .catch(this.handleGetError); 
    } 

    postNotification(notification: Notification): Observable<number> { 
    let id = notification.notificationId; 
    let requestUrl = this._notificationUrl + (id ? "/" + id : ""); 
    return this._http.post(requestUrl, notification) 
     .map((response: Response) => <number>response.json()) 
     .catch(this.handlePostError); 
    } 

    private handleGetError(error: Response) { 
    console.error(error); 
    return Observable.throw('Error retrieving existing notification(s)!'); 
    } 

    private handlePostError(error: Response) { 
    console.error(error); 
    return Observable.throw('Error while attempting to save notification!'); 
    } 
} 

और सेवा ठीक से चलाने के लिए लगता है - मैं देख सकता हूँ कि अंत बिंदु सफलतापूर्वक डेटा वापस आती है और मैं देख सकता हूँ कि जब मैं डेटा को देखने के सही लगती है मेरी Augury क्रोम एक्सटेंशन के साथ NotificationEditComponent। लेकिन डेटा टेम्पलेट में नहीं दिखाया गया है, और यूआरएल में रूट /maintenance/list पर आता है भले ही /maintenance/edit/:id रूट के लिए टेम्पलेट अभी भी प्रदर्शित हो।

अद्यतन 2: के उत्पादन

constructor(private _router: Router) { 
    this._router.events.pairwise().subscribe((event) => { 
    console.log(event); 
    }); 
} 

यहाँ है जब मैं "संपादित में से एक पर क्लिक करें:

@ user3249448 ने सुझाव दिया है, मैं कुछ डिबगिंग के लिए मेरी AppComponent के लिए निम्न जोड़ा "लिंक:

Route logging

+0

क्या आप हालिया कोणीय 2 संस्करण का उपयोग कर रहे हैं? कुछ समय पहले एक मुद्दा था जिसने इस व्यवहार को जन्म दिया लेकिन कुछ समय पहले AFAIR को ठीक कर दिया गया था। –

+0

वाइल्डकार्ड मार्ग को हटाने का प्रयास करें और देखें कि समस्या दूर हो गई है या नहीं। मुझे सूची में आखिरी होने की आवश्यकता वाले वाइल्डकार्ड मार्गों के बारे में कुछ पढ़ना याद है, और मुझे यकीन नहीं है कि आपकी कॉन्फ़िगरेशन में यह मामला है। – wolfhoundjesse

+0

मैं ** 2.4.8 **, और '@ कोणीय/राउटर' संस्करण ** 3.4.8 ** का उपयोग कर रहा हूं। और समस्या अभी भी होती है, यहां तक ​​कि वाइल्डकार्ड मार्ग के बिना भी। –

उत्तर

5

अंततः @ user3249448 से डिबगिंग सहायता प्राप्त करने के बाद समस्या को हल करने में सक्षम था।

बाहर कर देता है मैं इस NavigationError हो रही थी, भले ही कोई त्रुटि कंसोल के लिए लॉग इन किया जा रहा था:

enter image description here

यहाँ पूर्ण स्टैक ट्रेस किया गया था:, तो अनिवार्य रूप से

TypeError: Cannot read property 'notificationId' of undefined 
    at CompiledTemplate.proxyViewClass.View_NotificationEditComponent0.detectChangesInternal (/MaintenanceModule/NotificationEditComponent/component.ngfactory.js:487:49) 
    at CompiledTemplate.proxyViewClass.AppView.detectChanges (http://localhost:4200/vendor.bundle.js:80125:14) 
    at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (http://localhost:4200/vendor.bundle.js:80320:44) 
    at CompiledTemplate.proxyViewClass.AppView.internalDetectChanges (http://localhost:4200/vendor.bundle.js:80110:18) 
    at CompiledTemplate.proxyViewClass.View_NotificationEditComponent_Host0.detectChangesInternal (/MaintenanceModule/NotificationEditComponent/host.ngfactory.js:29:19) 
    at CompiledTemplate.proxyViewClass.AppView.detectChanges (http://localhost:4200/vendor.bundle.js:80125:14) 
    at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (http://localhost:4200/vendor.bundle.js:80320:44) 
    at ViewRef_.detectChanges (http://localhost:4200/vendor.bundle.js:60319:20) 
    at RouterOutlet.activate (http://localhost:4200/vendor.bundle.js:65886:42) 
    at ActivateRoutes.placeComponentIntoOutlet (http://localhost:4200/vendor.bundle.js:24246:16) 
    at ActivateRoutes.activateRoutes (http://localhost:4200/vendor.bundle.js:24213:26) 
    at http://localhost:4200/vendor.bundle.js:24149:58 
    at Array.forEach (native) 
    at ActivateRoutes.activateChildRoutes (http://localhost:4200/vendor.bundle.js:24149:29) 
    at ActivateRoutes.activate (http://localhost:4200/vendor.bundle.js:24123:14) 

मेरी मेरी वेब सेवा पर कॉल करने से पहले टेम्पलेट प्रस्तुत किया जा रहा था, और मेरा टेम्पलेट ठीक से प्रस्तुत नहीं किया जा सका क्योंकि notificationundefined था, इसलिए मुझे यहमिला, जो वर्णित व्यवहार का कारण बनता है (ऐसा लगता है कि इस त्रुटि को आपके AppComponent में अतिरिक्त डिबगिंग कोड जोड़ने के बिना कंसोल पर लॉग इन होना चाहिए?)।

इसे ठीक करने के लिए सभी मैं करना था मेरी fieldset कि notification बारे में सभी जानकारी निहित करने के लिए एक *ngIf जोड़ने था।

<p-fieldset [legend]="'Edit Notification'" *ngIf="notification"> 

और अब वेब टेम्पलेट से डेटा लौटने के बाद मेरा टेम्पलेट ठीक से लोड हो जाता है।

+0

नि: शुल्क युक्ति, आप एल्विस ऑपरेटर का भी उपयोग कर सकते हैं http://stackoverflow.com/questions/34833358/angular-2-typeerror-l-thing0-is-undefined-in-thing-title-in-appcomponent/34833436#34833436 –

+0

आधिकारिक दस्तावेज़ यहां: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#safe-navigation-operator –

0

मेरा अनुमान होगा कि आपके ब्राउज़र एक वास्तविक ली के रूप में अपनी संपादित करें लिंक व्याख्या करने के तरीके ऐसा करने के बजाय एनके जो आप करना चाहते हैं। यह इस तथ्य पर आधारित है कि आप फ्लैश-लगता है जैसे ब्राउज़र प्रश्न में लिंक पर जाने का प्रयास कर रहा है।

एक एंकर टैग से अधिसूचना को एक साधारण अवधि या div में संपादित करने के लिए अपनी अधिसूचना सूची में क्लिक करने वाले आइटम को बदलने का प्रयास करें। यदि आपको फ़्लैश नहीं मिलता है, तो आप जानते हैं कि यह आपका मुद्दा था।

+0

नहीं, एक div में बदलना काम नहीं करता है। और यह वास्तविक पृष्ठ नहीं है जो चमकता है। पृष्ठ वास्तव में संपादन टेम्पलेट को सही ढंग से प्रस्तुत करता है (मॉडल के अलावा सही ढंग से इनपुट करने के लिए बाध्यकारी नहीं है), यह केवल पता बार है जो सही संपादन मार्ग पर चमकता है, फिर सूची मार्ग पर वापस जाता है, जबकि संपादन टेम्पलेट वास्तविक पृष्ठ पर प्रदर्शित होता है । –

संबंधित मुद्दे