You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
}

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

  1. Shared Singleton Service: By removing the component-level providers, both components use the same PropertyService instance, so the selectedProperty value is shared correctly.
  2. Async Data Handling: BehaviorSubject stores the latest value, so new subscribers (like PropertyinfoComponent) get the current value immediately—even if it was set before the component initialized.
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:52:19