NativeScript/Angular路由传递JSON数据问题求助
Hey, let's figure out why your selectedProperty is coming up undefined in the PropertyinfoComponent!
The core issue here is unshared service instances. You added providers: [PropertyService] to the @Component metadata of PropertyComponent, which tells Angular to create a separate, component-specific instance of PropertyService instead of using the singleton instance you registered in AppModule. So when you assign selectedProperty in PropertyComponent, you're modifying that component's private service instance, while PropertyinfoComponent is injecting the root-level singleton—these are two entirely separate objects, hence the undefined value.
Step 1: Fix Service Instance Sharing
First, remove the component-level providers array from PropertyComponent to ensure both components use the same singleton service:
// property.component.ts @Component({ selector: 'app-property', templateUrl: 'pages/property/property.component.html', // Delete this line: providers: [PropertyService] }) export class PropertyComponent implements OnInit { // ... rest of your code remains the same }
Step 2: Optimize Data Flow (Optional but Recommended)
While the above fix will resolve the immediate issue, your current service uses plain properties to store data, which doesn't handle asynchronous scenarios well (like the http.get call finishing after component initialization). Using RxJS BehaviorSubject will make your data management more robust:
// property.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject } from 'rxjs'; @Injectable() export class PropertyService { // Manage property list with BehaviorSubject (initial value: empty array) private propertyDataSubject = new BehaviorSubject<any[]>([]); public propertyData$ = this.propertyDataSubject.asObservable(); // Manage selected property with BehaviorSubject (initial value: null) private selectedPropertySubject = new BehaviorSubject<any>(null); public selectedProperty$ = this.selectedPropertySubject.asObservable(); constructor(private http: HttpClient) { this.loadProperties(); } loadProperties() { this.http.get<any[]>('/pages/property/property.json').subscribe( (data) => { this.propertyDataSubject.next(data); // Push new data to subscribers } ) } // Encapsulate setting selected property setSelectedProperty(property: any) { this.selectedPropertySubject.next(property); } }
Step 3: Update Components to Subscribe to Data Streams
Modify PropertyComponent to subscribe to the property list, ensuring the view updates once the async data loads:
// property.component.ts import { Component, OnInit } from '@angular/core'; import { Router } from "@angular/router"; import { PropertyService } from './property.service'; @Component({ selector: 'app-property', templateUrl: 'pages/property/property.component.html', }) export class PropertyComponent implements OnInit { public propertyData: any[] = []; constructor(private router: Router, private propertyService: PropertyService) {} ngOnInit() { // Subscribe to property list updates this.propertyService.propertyData$.subscribe(data => { this.propertyData = data; }); } details(item: any) { this.propertyService.setSelectedProperty(item); console.log(JSON.stringify(item)); this.router.navigate(["/propertyinfo"]); } }
Then update PropertyinfoComponent to subscribe to the selected property, ensuring it always gets the latest value:
// propertyinfo.component.ts import { Component, OnInit, OnDestroy } from '@angular/core'; import { PropertyService } from '../property/property.service'; import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-propertyinfo', templateUrl: 'pages/propertyinfo/propertyinfo.component.html' }) export class PropertyinfoComponent implements OnInit, OnDestroy { public selectedProperty: any; private subscription: Subscription; constructor(private propertyService: PropertyService, private router: Router) {} ngOnInit() { // Subscribe to selected property changes this.subscription = this.propertyService.selectedProperty$.subscribe(property => { this.selectedProperty = property; console.log(JSON.stringify(this.selectedProperty)); // Now outputs valid JSON }); } // Unsubscribe on component destroy to avoid memory leaks ngOnDestroy() { this.subscription.unsubscribe(); } }
Why This Works
- Shared Singleton Service: By removing the component-level
providers, both components use the samePropertyServiceinstance, so theselectedPropertyvalue is shared correctly. - Async Data Handling:
BehaviorSubjectstores the latest value, so new subscribers (likePropertyinfoComponent) get the current value immediately—even if it was set before the component initialized. - Automatic View Updates: Subscribing to streams ensures components update automatically when data changes, eliminating issues from async data loading.
Run your project now, and when you click an item, PropertyinfoComponent should correctly log the selected JSON data!
内容的提问来源于stack exchange,提问作者Tienus McVinger

