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

如何在Angular中获取当前课程ID并通过props传入loadOneCourse方法?

Hey, let's tackle your two Angular/NgRx questions one by one—they're pretty common scenarios, so I'll break this down clearly for you:

1. How to Get the Current Course ID in Angular

There are three common ways to grab the current course ID, depending on where it's stored:

  • From Route Parameters (most common if it's in your URL)
    If your route looks like /courses/:courseId, use ActivatedRoute to pull the ID from the URL:

    import { ActivatedRoute } from '@angular/router';
    import { takeUntil } from 'rxjs';
    
    constructor(private route: ActivatedRoute) {}
    
    ngOnInit(): void {
      this.route.paramMap.pipe(
        takeUntil(this.destroySubject$),
        map(params => params.get('courseId')) // Gets the ID from the route
      ).subscribe(courseId => {
        if (courseId) {
          // Use the courseId here
        }
      });
    }
    
  • From NgRx Store (if it's already in your state)
    Since you're using selectCourseToBeEnrolled, you can either select the ID directly (if you have a dedicated selector) or extract it from the course object:

    // Option 1: Dedicated selector (cleaner if you have one)
    this._store.select(selectCurrentCourseId).pipe(takeUntil(this.destroySubject$))
      .subscribe(courseId => { /* Use the ID */ });
    
    // Option 2: Extract from the existing course selector
    this._store.select(selectCourseToBeEnrolled).pipe(
      takeUntil(this.destroySubject$),
      filter(course => !!course),
      map(course => course.id)
    ).subscribe(courseId => { /* Use the ID */ });
    
  • From Component Input (if passed from a parent component)
    If a parent component is passing the ID down, use an @Input() property:

    @Input() courseId: string; // Or number, depending on your ID type
    
    ngOnInit(): void {
      if (this.courseId) {
        // Use the courseId here
      }
    }
    
2. Passing the Course ID to loadOneCourse in Your Code

Your current code has a nested subscription (which we should avoid for cleaner RxJS) and needs to pass the course ID to loadOneCourse. Here's a revised version that fixes both issues:

import { EMPTY, switchMap } from 'rxjs';

ngOnInit(): void { 
  this._store.select(AuthSelectors.isLoggedIn).pipe( 
    takeUntil(this.destroySubject$),
    // Switch to the course selector only if user is logged in
    switchMap((isLoggedIn) => {
      if (!isLoggedIn) {
        return EMPTY; // Do nothing if user isn't logged in
      }
      // Get the course to enroll, filter out null/undefined, take only the first value
      return this._store.select(selectCourseToBeEnrolled).pipe(
        filter(value => !!value),
        first()
      );
    }),
    // Now we have the valid course object—dispatch both actions
    tap((course) => {
      this._store.dispatch(enrollWhatToLearnCourse({ 
        id: course.id, 
        title: course.title, 
        enroll: false 
      }));
      // Pass the course ID to loadOneCourse here
      this._store.dispatch(loadOneCourse({ id: course.id }));
    })
  ).subscribe(); 
}

Key Changes:

  • Removed nested subscriptions: Used switchMap to flatten the observable chain—this is a best practice in RxJS to avoid callback hell.
  • Guaranteed valid course data: The filter(value => !!value) and first() ensure we only proceed when we have a valid course object with an ID.
  • Passed the ID directly: We extract course.id from the selected course and pass it as the id property in the loadOneCourse action props.

If your course ID comes from the route instead of the store, you can adjust the code to combine the route parameter stream with the logged-in state:

import { combineLatest } from 'rxjs';

ngOnInit(): void { 
  combineLatest([
    this._store.select(AuthSelectors.isLoggedIn).pipe(takeUntil(this.destroySubject$)),
    this.route.paramMap.pipe(
      takeUntil(this.destroySubject$),
      map(params => params.get('courseId')),
      filter(Boolean) // Ensure we have a valid ID
    )
  ]).pipe(
    tap(([isLoggedIn, courseId]) => {
      if (isLoggedIn) {
        // If you need the course title for enrollWhatToLearnCourse, you might need to fetch it first or select it from store
        this._store.dispatch(enrollWhatToLearnCourse({ 
          id: courseId, 
          title: '', // Replace with actual title if needed
          enroll: false 
        }));
      }
      this._store.dispatch(loadOneCourse({ id: courseId }));
    })
  ).subscribe(); 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:52:34