【发布时间】:2020-06-09 18:51:24
【问题描述】:
我创建了一个角度覆盖组件来显示有关打开覆盖组件的卡片的信息(通过单击卡片中的信息按钮);打开时,它会进行 API 调用以从 API 中检索一些数据,并在单击时传递参数。当前行为需要点击两三下才能显示正确的数据:
- 如果是页面加载后的第一次点击,则会引发错误。 (数据已检索但未显示。覆盖未打开。我已将错误粘贴在下面)
- 再次点击请求数据,打开覆盖并显示数据。
- 单击不同的卡需要 3 次尝试才能获得要显示的正确数据。
- 首次点击请求新数据并打开覆盖以前的卡片数据。
- 第二次点击页面以关闭此叠加层
- 第三次点击再次请求新数据并打开包含新数据的叠加层。
工艺流程:
打开 > createOverlay > getOverlayConfig > attachDialogContainer > createInjector > TeamInfoOverlayComponent > 关闭
第一次点击时出错:
错误 NullInjectorError: R3InjectorError(AppModule)[InjectionToken TEAM_INFO_DIALOG_DATA -> InjectionToken TEAM_INFO_DIALOG_DATA -> InjectionToken TEAM_INFO_DIALOG_DATA]: NullInjectorError:没有 InjectionToken TEAM_INFO_DIALOG_DATA 的提供者! 在 NullInjector.get
overlay-ref.ts
import { OverlayRef } from '@angular/cdk/overlay';
export class TeamInfoOverlayRef {
constructor(private overlayRef: OverlayRef) { }
close(): void {
this.overlayRef.dispose();
console.log('in close');
}
}
overlay.component.ts
@Component({
selector: 'team-info-overlay',
template: `
<mat-card class="example-card" class="mat-elevation-z5">
<mat-card-header>Team Members</mat-card-header>
<mat-card-content *ngFor="let member of team">
<mat-card-subtitle>
{{member.first_name + member.last_name}} {{member.role_name}} {{member.email}} {{member.total_chapters}} {{member.added}} {{member.tc_accepted}}
</mat-card-subtitle>
</mat-card-content>
</mat-card>
`,
styles: [`
:host {
display: flex;
flex-direction: column;
align-items: center;
}
h1 {
margin: 0;
padding: 1em;
}
img {
width: 100%;
max-width: 500px;
height: auto;
}
.overlay-content {
padding: 1em;
}
`]
})
export class TeamInfoOverlayComponent {
constructor(
public dialogRef: TeamInfoOverlayRef,
@Inject(TEAM_INFO_DIALOG_DATA) public team: any) {
console.log('in TeamInfoOverlayComponent constructor');
}
}
overlay.service.ts
interface TeamInfoDialogConfig {
panelClass?: string;
hasBackdrop?: boolean;
backdropClass?: string;
Organizers?: Organizers[];
}
const DEFAULT_CONFIG: TeamInfoDialogConfig = {
hasBackdrop: true,
backdropClass: 'dark-backdrop',
panelClass: 'tm-file-preview-dialog-panel',
Organizers: null
}
@Injectable()
export class TeamInfoOverlayService {
constructor(
private injector: Injector,
private overlay: Overlay) {
console.log('TeamInfoOverlayService constructor');
}
open(config: TeamInfoDialogConfig = {}) {
console.log('in open');
// Override default configuration
const dialogConfig = { ...DEFAULT_CONFIG, ...config };
// Returns an OverlayRef which is a PortalHost
const overlayRef = this.createOverlay(dialogConfig);
// Instantiate remote control
const dialogRef = new TeamInfoOverlayRef(overlayRef);
const overlayComponent = this.attachDialogContainer(overlayRef, dialogConfig, dialogRef);
overlayRef.backdropClick().subscribe(() => dialogRef.close());
// overlayRef.backdropClick().(_ => dialogRef.close());
return dialogRef;
}
private createOverlay(config: TeamInfoDialogConfig) {
console.log('in createOverlay');
const overlayConfig = this.getOverlayConfig(config);
return this.overlay.create(overlayConfig);
}
private attachDialogContainer(overlayRef: OverlayRef, config: TeamInfoDialogConfig, dialogRef: TeamInfoOverlayRef) {
console.log('in attachDialogContainer');
const injector = this.createInjector(config, dialogRef);
const containerPortal = new ComponentPortal(TeamInfoOverlayComponent, null, injector);
const containerRef: ComponentRef<TeamInfoOverlayComponent> = overlayRef.attach(containerPortal);
return containerRef.instance;
}
private createInjector(config: TeamInfoDialogConfig, dialogRef: TeamInfoOverlayRef): PortalInjector {
console.log('in createInjector');
const injectionTokens = new WeakMap();
injectionTokens.set(TeamInfoOverlayRef, dialogRef);
injectionTokens.set(TEAM_INFO_DIALOG_DATA, config.Organizers);
return new PortalInjector(this.injector, injectionTokens);
}
private getOverlayConfig(config: TeamInfoDialogConfig): OverlayConfig {
console.log('in getOverlayConfig');
const positionStrategy = this.overlay.position()
.global()
.centerHorizontally()
.centerVertically();
const overlayConfig = new OverlayConfig({
hasBackdrop: config.hasBackdrop,
backdropClass: config.backdropClass,
// panelClass: config.panelClass,
scrollStrategy: this.overlay.scrollStrategies.block(),
positionStrategy
});
return overlayConfig;
}
}
overlay.token.ts
export const TEAM_INFO_DIALOG_DATA = new InjectionToken<Organizers>('TEAM_INFO_DIALOG_DATA');
感谢任何指导。谢谢!
【问题讨论】:
标签: angular angular-cdk