我的路线中有这个层次结构:
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; {”
我希望我设法解释我想要完成的事情:)
答案 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;