我遇到了一个真正的问题,即将一个变量从服务(LibraryService)传递到一个在目录结构中更深层次的组件(ReadingPaneComponent)。这是在我赢得一场激烈的战斗之后,从一个更深层次的组件(AuthorsComponent)将此变量引入服务。因此,有效地,ReadingPaneComponent是AuthorsComponent的“阿姨/叔叔”,因此我尝试通过现有的LibraryService发送变量,该服务还用于从我的后端数据库中提取数据。
我要做的就是将最多五位数字传递给ReadingPaneComponent,这些数字代表一本书的ID。服务完全可以很好地检测出这个数字,但我不能因为爱而没有金钱将它作为“未定义”之外的其他内容传入ReadingPaneComponent。当用户点击书名时,我也调用了AuthorsComponent在ReadingPaneComponent中定义的方法,因此这可能是异步调用的问题,或者是ReadingPaneComponent中的方法应该处于什么生命周期钩子中(当前ngOnInit但我认识到这一点)可能是错的,并尝试了无可比拟的替代方案。)
这是来自 library.service.ts 的相关代码: -
import { Injectable, Component, Input } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Language } from '../shared/language.model';
import { Author } from '../shared/author.model';
import { Book } from '../shared/book.model';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs/observable';
import { Subject } from 'rxjs/Subject';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import {
AngularFireDatabase,
AngularFireList,
AngularFireObject } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';
@Injectable()
export class LibraryService {
private chosenBookSource = new Subject<number>();
chosenBook$ = this.chosenBookSource.asObservable();
// MORE CODE HERE
chosenBook(data) {
console.log(data); //This shows the correct ID of the book clicked by the user, so I know this is working properly.
this.chosenBookSource.next(data);
return data;
}
这是来自 reading-pane.component.ts : -
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { LibraryService } from '../library.service';
import { Language } from '../../shared/language.model';
import { Author } from '../../shared/author.model';
import { Book } from '../../shared/book.model';
import { Observable } from 'rxjs/observable';
@Component({
selector: 'app-reading-pane',
templateUrl: './reading-pane.component.html',
styleUrls: ['./reading-pane.component.css'],
providers: [LibraryService]
})
export class ReadingPaneComponent implements OnInit, OnDestroy {
@Input() bookPGID: number;
public bookHTML;
constructor(private libraryService: LibraryService) {
}
ngOnInit() {
console.log(this.libraryService.chosenBook$);
this.libraryService.chosenBook$.subscribe(data => (this.bookPGID = data));
console.log(this.bookPGID);
this.libraryService
.loadBook(this.bookPGID)
.subscribe((book: Observable<any>) => (this.bookHTML = book));
}
AuthorsComponent中的调用有效,因为它确实触发了ReadingPaneComponent中的loadBook
函数,只是ID号在从LibraryService到ReadingPaneComponent的旅程中无法存活。
感谢任何帮助。
答案 0 :(得分:0)
看起来问题在于声明了LibraryService。
如果ReadingPaneComponent
内部使用了AuthorsComponent
,例如:
<!-- AuthorsComponent.html -->
<h1>Authors</h1>
...
<reading-pane-component></reading-pane-component>
然后尝试从阅读窗格的providers: [LibraryService]
装饰器中删除@component
。该声明是为阅读窗格组件的每个实例创建一个新的LibraryService实例。如果从阅读窗格中删除该声明,它将从其父级继承LibraryService,即authors组件。
如果您的阅读窗格未在作者内部使用,请尝试在您的应用程序模块中声明LibraryService提供程序。从作者和阅读窗格组件中删除providers: [LibraryService]
。然后将其添加到您应用的@NgModule
装饰器。
Have a look at this plnkr,您会看到:
src/app.ts
中声明的LibraryServiceOnce。在整个应用程序中,它产生的值是相同的src/AuthorsComponent.ts
中声明的LibraryService。它为作者组件的每个实例生成不同的值希望有所帮助!