访问父路线参数

时间:2018-05-20 22:03:50

标签: angular parameters routes

我的路线中有这个层次结构:

import { Routes } from '@angular/router';

import { AuthenticatedUserComponent } from './authenticated-user/authenticated-user.component';

import { DashboardComponent } from './dashboard/dashboard.component';
import { BookListComponent } from './book-list/book-list.component';
import { BooksByCategoryComponent } from './books-by-category/books-by-category.component';
import { BookDetailComponent } from './book-detail/book-detail.component';
import { BookDetailUserComponent } from './bookdetail-user/bookdetail-user.component';
import { BookMaintComponent } from './book-maint/book-maint.component';
import { ReviewDialogComponent } from './review-dialog/review-dialog.component';
import { SignInComponent } from '../fw/users/sign-in/sign-in.component';
import { RegisterUserComponent } from '../fw/users/register-user/register-user.component';
import { AuthGuard } from './services/auth-guard.service';
import { IsAdminGuard } from './services/is-admin-guard.service';

export const appRoutes: Routes = [  
 { path: 'signin', component: SignInComponent },
 { path: 'register', component: RegisterUserComponent },
 { path: 'authenticated', component: AuthenticatedUserComponent, canActivate: [AuthGuard],
children: [
  { path: '', canActivateChild: [AuthGuard], 
    children: [
      { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
      { path: 'dashboard', component: DashboardComponent },
      { path: 'book-list/:count', component: BookListComponent },
      { path: 'book-detail/:id/:operation', component: BookDetailComponent, canActivate: [IsAdminGuard] },
      {
        path: 'bookdetail-user/:id', component: BookDetailUserComponent,
        children: [
          { path: 'review-dialog/:id', component: ReviewDialogComponent }
        ]
      },
      { path: 'books-by-category/:categoryId', component: BooksByCategoryComponent },
      { path: 'book-maint', component: BookMaintComponent, canActivate: [IsAdminGuard] },
    ] }
] },
{ path: '', component: SignInComponent },
{ path: '**', component: SignInComponent }
];

在我的app.module中,我导入了我需要的所有内容(我将分享与我的问题相关的组件,因为我在这里分享的内容太多了)

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule, ReactiveFormsModule, FormGroup, FormBuilder } from 
'@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { FwModule } from '../fw/fw.module';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SettingsComponent } from './settings/settings.component';
import { appRoutes } from './app.routing';
import { AppConfig } from './app.config';
import { BookListComponent } from './book-list/book-list.component';
import { BooksByCategoryComponent } from './books-by-category/books-by-category.component';
import { BookDetailComponent } from './book-detail/book-detail.component';
import { BookDetailUserComponent } from './bookdetail-user/bookdetail-user.component';
import { BookMaintComponent } from './book-maint/book-maint.component';
import { BookService } from './services/book.service';
import { ReviewService } from './services/review.service';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatDatepickerModule, MatDialogModule } from '@angular/material';
import { ReviewDialogComponent } from './review-dialog/review-dialog.component';

@NgModule({
  declarations: [
    AppComponent,
    DashboardComponent,
    BookListComponent,
    BooksByCategoryComponent,
    BookDetailComponent,
    BookDetailUserComponent,
    ReviewDialogComponent,
    BookMaintComponent,
    AuthenticatedUserComponent,
    ImagePanelComponent,
    BookPanelComponent,
    BookFilterPipe,
    OrderByPipe,
    StarComponent
  ],
 exports: [
// Material
MatDatepickerModule,
MatDialogModule,
MatFormFieldModule,
MatFormFieldModule
],
imports: [
   BrowserModule,
   FormsModule,
   ReactiveFormsModule,
   HttpModule,
   FwModule,
   MatDatepickerModule,
   MatNativeDateModule,
   MatFormFieldModule,
   RouterModule.forRoot(appRoutes)
],
providers: [
   UserService,
   AuthGuard,
   IsAdminGuard,
   AlertService,
   BookService,
   PagerService,
   ReviewService,
   AuthenticationService,
   CustomDateAdapter,
   AppConfig
 ],
 schemas: [CUSTOM_ELEMENTS_SCHEMA],
 bootstrap: [AppComponent],
 entryComponents: [ReviewDialogComponent],
})
export class AppModule { }

现在,在我的BookDetailUserComponent中,我有一个按钮,onclick,显示一个模式,用户可以在其中添加评论,介绍评论和1到5的星。问题是我必须将bookId发送到ReviewDialogComponent,这就是为什么我试图将父params(BookDetailUserComponent params)放入子组件(ReviewDialog)

这是来自BookDetailUserComponent的代码:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { Book } from '../view-models/book';
import { Review } from '../view-models/review';
import { BookService } from '../services/book.service';
import { ReviewService } from '../services/review.service';
import { MatDialog, MatDialogConfig, MatDialogRef, MatSelectModule, 
   MatButtonModule } from "@angular/material";
import { ReviewDialogComponent } from "../review-dialog/review- 
 dialog.component";

@Component({
  selector: 'app-bookdetail-user',
  templateUrl: 'bookdetail-user.component.html'
})

export class BookDetailUserComponent implements OnInit {
 book: Book;
 review: Review;
 errorMessage: string;
 private sub: Subscription;

 reviewDialogRef: MatDialogRef<ReviewDialogComponent>;

 constructor(private route: ActivatedRoute,
   private router: Router,
   private bookService: BookService,
   private reviewService: ReviewService,
   private dialog: MatDialog) { }

ngOnInit(): void {
   this.bookService.getBook(this.route.snapshot.params['id'])
     .subscribe((book: Book) => { this.book = book });
}

addReview(review: Review) {
   const dialogConfig = new MatDialogConfig();

   dialogConfig.disableClose = true;
   dialogConfig.autoFocus = true;

   const dialogRef = this.dialog.open(ReviewDialogComponent,
     dialogConfig);

   dialogRef.afterClosed().subscribe(
    //val => console.log("Dialog output:", val)
    (review: Review) => {
      console.log("Dialog output:", review)
      }
  );
 }
}  

BookDetailUserComponent的模板如下所示:

<div class='panel-body'>
  <div class='row'>
     <div class='col-md-6'> ... </div>

     <div class='col-md-6'>
     <img class='center-block img-responsive'
         [style.width.px]='300'
         [style.margin.px]='3'
         [src]='book.imageUrl'
         [title]='book.title'>
      <button mat-button class="raised-button accent"
              (click)="addReview($event)">
        Add Review
      </button>
      </div>
   </div>
</div>

在我的ReviewDialogComponent中,我有:

import { Component, Inject, OnInit, ViewEncapsulation, Input } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatButtonModule} from "@angular/material";
import { Book } from '../view-models/book';
import { Review } from '../view-models/review';
import { BookService } from '../services/book.service';
import { ReviewService } from '../services/review.service';
import { FormBuilder, Validators, FormGroup } from "@angular/forms";
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { ActivatedRoute, Router, Params } from '@angular/router';

@Component({
  selector: 'review-dialog',
  templateUrl: './review-dialog.component.html',
  styleUrls: ['./review-dialog.component.css']
})
export class ReviewDialogComponent implements OnInit {

 errorMessage: string;
 feedbackForm: FormGroup;
 bookId: number;
 userId: number;
 date: Date;
 comments: string;
 rating: number;
 review: Review;

 private sub: any;
 private parentRouteId: number;

 public options = [
   { "id": 1, "name": "1 star" },
   { "id": 2, "name": "2 stars" },
   { "id": 3, "name": "3 stars" },
   { "id": 4, "name": "4 stars" },
   { "id": 5, "name": "5 stars" }
 ]
   public selected = this.options[0].id;

  //@Input() bId: number;

  constructor(
    private fb: FormBuilder,
    private route: ActivatedRoute,
    private router: Router,
    private dialogRef: MatDialogRef<ReviewDialogComponent>,
    private reviewService: ReviewService,
    @Inject(MAT_DIALOG_DATA) public data: any) {

      //const parentActivatedRoute = route.pathFromRoot();
     //let id = parentActivatedRoute.snapshot.parent.params['id'];  
  }

ngOnInit() {

  this.sub = this.route.parent.params.subscribe(params => {
     this.parentRouteId = +params["id"];
     console.log(this.parentRouteId);
   });

   var currentUser = JSON.parse(localStorage.getItem('currentUser'));
   this.feedbackForm = this.fb.group({
      bookId: null,
      userId: null,
      date: Date,
      comments: '',
      rating: null
   });
   this.feedbackForm.setValue({
      bookId: this.bookId,
      userId: [currentUser.userId],
      date: [new Date()],
      comments: [''],
      rating: [this.selected],
   });
  }

 save() {
    this.dialogRef.close(this.feedbackForm.value);
    if (this.feedbackForm.dirty && this.feedbackForm.valid) {
      // Copy the form values over the user object values
      let r = Object.assign({}, this.review, this.feedbackForm.value);

     this.reviewService.createReview(r)
       .subscribe(
       () => this.onCreateComplete(),
       (error: any) => this.errorMessage = <any>error
     );
   } else if (!this.feedbackForm.dirty) {
      this.onCreateComplete();
  }
 }

 onCreateComplete(): void {
   // Reset the form to clear the flags
   this.feedbackForm.reset();
   this.router.navigate(['/authenticated/dashboard']);
 }

close() {
   this.dialogRef.close();
}

}

我的ReviewDialog html看起来像这样:

<h1 mat-dialog-title>Add review</h1>

<form [formGroup]="feedbackForm">
  <textarea placeholder="Comments"
        formControlName="comments">
  </textarea><br>
 <br>
  <select formControlName="rating">
     <option *ngFor="let option of options" [value]="option.id">{{ option.name }}</option>
  </select><br>
  <br>
 <div>
    <button class="mat-raised-button" (click)="close()">Close</button>
    <button class="mat-raised-button" (click)="save()">Save</button>
 </div>
 </form>

现在我收到的错误是“ ERROR TypeError:无法在ReviewDialogComponent.ngOnInit(review-dialog.component.ts:61)”中读取null的属性'params' 第61行是“this.sub = this.route.parent.params.subscribe(params =&gt; {”

我希望我设法解释我想要完成的事情:)

1 个答案:

答案 0 :(得分:1)

所以,我设法让它工作而不访问父路径参数,我在addReview()方法中添加了这个,在 dialogRef.afterClosed()之前:

template<class T, size_t M, size_t N>
class matrix
{
public:
    matrix<T,M,N>& operator*=(const matrix<T,M,N>&);
};

// Generic version.
template<class T, size_t M, size_t N>
void inplace_dot(matrix<T,M,N>& a, matrix<T,M,N> const& b); 

// Overload for 2x2 matrix.
template<class T>
void inplace_dot(matrix<T,2,2>& a, matrix<T,2,2> const& b);

template<class T, size_t M, size_t N>
matrix<T,M,N>& matrix<T,M,N>::operator*=(const matrix<T,M,N>& b)
{
    inplace_dot(*this, b);
    return *this;
}

,这在ngOnInit()

的评论组件中
dialogRef.componentInstance.bookId = this.book.bookId;