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

Angular:在ngFor中传递单个对象至路由链接组件

Hey, let's break down how you can pass the diary object to your page-view component when clicking those links. Since you're dealing with route-based navigation (not direct parent-child communication), there are a couple of solid approaches here—let's start with the service method you're curious about, then cover other options too.

First, a quick note: Your diary property in VolumeLinksComponent is typed as String, but it should be an array (since you're using *ngFor on it). I'll fix that in the code examples below.


Method 1: Shared Service (Best for complex objects/avoiding URL exposure)

This is the approach you mentioned wanting to learn. We'll create a service to hold the selected diary object, set it when the link is clicked, and subscribe to it in the page-view component.

Step 1: Create the shared service

// diary-shared.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class DiarySharedService {
  // BehaviorSubject holds the current value and emits it to new subscribers
  private selectedDiarySubject = new BehaviorSubject<any | null>(null);
  selectedDiary$ = this.selectedDiarySubject.asObservable();

  setSelectedDiary(diary: any) {
    this.selectedDiarySubject.next(diary);
  }
}

First, add a click handler to your <a> tag to pass the diary object to the service:

<!-- volume-links.component.html -->
<ul class="navigation">
 <li *ngFor="let d of diary">
 <a 
   id="{{d.notebook_id}}" 
   routerLink="/page-view" 
   routerLinkActive="active"
   (click)="onDiaryClick(d)"
 >Volume {{d.notebook_id}}, {{ d.date }}, {{ d.volume_id }}, Add MS {{ d.ms_id }}</a>
 </li>
</ul>

Then update the component class to inject the service and handle the click:

// volume-links.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DiarySharedService } from './diary-shared.service'; // Import the service

@Component({
 selector: 'app-volume-links',
 templateUrl: './volume-links.component.html',
 styleUrls: ['./volume-links.component.scss'],
})
export class VolumeLinksComponent implements OnInit {
 diary: any[] = []; // Fix the type to array

 constructor(
   private http: HttpClient,
   private diarySharedService: DiarySharedService // Inject the service
 ) { }

 ngOnInit() {
 this.http.get('/api/diaries').subscribe(data => {
 this.diary = data["data"]["docs"];
 console.log(this.diary);
 })
 }

 onDiaryClick(diary: any) {
   // Set the selected diary in the service
   this.diarySharedService.setSelectedDiary(diary);
 }
}

Step 3: Get the selected diary in PageView component

Subscribe to the service's observable to receive the diary object:

// page-view.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DiarySharedService } from './diary-shared.service';
import { Subscription } from 'rxjs';

@Component({
 selector: 'app-page-view',
 templateUrl: './page-view.component.html',
 styleUrls: ['./page-view.component.scss'],
})
export class PageViewComponent implements OnInit, OnDestroy {
 selectedDiary: any;
 private subscription: Subscription | undefined;

 constructor(private diarySharedService: DiarySharedService) { }

 ngOnInit() {
   // Subscribe to the selected diary updates
   this.subscription = this.diarySharedService.selectedDiary$.subscribe(diary => {
     if (diary) {
       this.selectedDiary = diary;
       // Add your logic here (e.g., load related data)
     }
   });
 }

 ngOnDestroy() {
   // Clean up the subscription to prevent memory leaks
   if (this.subscription) {
     this.subscription.unsubscribe();
   }
 }
}

Method 2: Route State (Angular 7+, no service needed)

If you don't want to use a service, you can pass the object directly in the route state (it won't show up in the URL, but will be lost if the user refreshes the page).

<!-- volume-links.component.html -->
<ul class="navigation">
 <li *ngFor="let d of diary">
 <a 
   id="{{d.notebook_id}}" 
   [routerLink]="['/page-view']"
   [state]="{ selectedDiary: d }"
   routerLinkActive="active"
 >Volume {{d.notebook_id}}, {{ d.date }}, {{ d.volume_id }}, Add MS {{ d.ms_id }}</a>
 </li>
</ul>

Get state in PageView component

// page-view.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
 selector: 'app-page-view',
 templateUrl: './page-view.component.html',
 styleUrls: ['./page-view.component.scss'],
})
export class PageViewComponent implements OnInit {
 selectedDiary: any;

 constructor(private route: ActivatedRoute) { }

 ngOnInit() {
   // Retrieve the state from the route snapshot
   const navigation = this.route.snapshot.navigation;
   if (navigation?.extras.state) {
     this.selectedDiary = navigation.extras.state['selectedDiary'];
   }
 }
}

Method 3: Query Params (URL-visible, simple objects)

If you don't mind the diary data appearing in the URL, you can serialize the object to a JSON string and pass it as a query parameter.

<!-- volume-links.component.html -->
<ul class="navigation">
 <li *ngFor="let d of diary">
 <a 
   id="{{d.notebook_id}}" 
   [routerLink]="['/page-view']"
   [queryParams]="{ diary: JSON.stringify(d) }"
   routerLinkActive="active"
 >Volume {{d.notebook_id}}, {{ d.date }}, {{ d.volume_id }}, Add MS {{ d.ms_id }}</a>
 </li>
</ul>

Parse params in PageView component

// page-view.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
 selector: 'app-page-view',
 templateUrl: './page-view.component.html',
 styleUrls: ['./page-view.component.scss'],
})
export class PageViewComponent implements OnInit {
 selectedDiary: any;

 constructor(private route: ActivatedRoute) { }

 ngOnInit() {
   this.route.queryParams.subscribe(params => {
     if (params['diary']) {
       this.selectedDiary = JSON.parse(params['diary']);
     }
   });
 }
}

内容的提问来源于stack exchange,提问作者Alcamech

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:04:59