我收到的错误是我以前在Angular应用中从未见过的。错误发生在Angular源代码的this line上。
当我退出并重新登录我的应用时会发生这种情况。我这样做的路径有一个可观察的观察点,并且当它向其流发出一个值时,观察到的任何东西都会更新值并且更改检测将运行,从而删除一些元素并添加一些其他元素。
我非常确定下面的组件会导致错误。任何人都可以看到任何明显的我做错了吗?我留下了我认为可能与bug相关的部分,并注释掉了其他所有内容。也许我在这里不恰当地使用ngTemplateOutlet
和ContentChild
......
组件:
@Component({
selector: 'paginated-infinite-scroll',
templateUrl: './paginated-infinite-scroll.component.html'
})
export class PaginatedInfiniteScrollComponent {
// ...
@ContentChild('results') resultsRef: TemplateRef<any>;
@ContentChild('noResults') noResultsRef: TemplateRef<any>;
@ContentChild('loading') loadingRef: TemplateRef<any>;
@ContentChild('loadingMore') loadingMoreRef: TemplateRef<any>;
// ...
}
模板:
<div infiniteScroll [infiniteScrollDistance]="2" [infiniteScrollThrottle]="300" [scrollWindow]="true" (scrolled)="scrolled()">
<ng-container *ngIf="result.items.length > 0 && !loading">
<ng-template [ngTemplateOutlet]="resultsRef"></ng-template>
</ng-container>
<ng-container *ngIf="result.items.length === 0 && !loading">
<ng-template [ngTemplateOutlet]="noResultsRef"></ng-template>
</ng-container>
<ng-container *ngIf="loading">
<ng-template [ngTemplateOutlet]="loadingRef"></ng-template>
</ng-container>
<ng-container *ngIf="loadingMore">
<ng-template [ngTemplateOutlet]="loadingMoreRef"></ng-template>
</ng-container>
</div>
用法:
<paginated-infinite-scroll [onScroll]="onScroll" [query]="query" [result]="result">
<ng-template #results>
// Loop through results here...
</ng-template>
<ng-template #noResults>
// Show no results message here...
</ng-template>
<ng-template #loading>
// Show loading spinner here...
</ng-template>
<ng-template #loadingMore>
// Show some other loading spinner here...
</ng-template>
</paginated-infinite-scroll>
答案 0 :(得分:0)
修正了此问题。该错误实际上并非来自我原始问题中的代码。我在指令中有一个可观察的,我从来没有取消订阅。该指令订阅了一个auth事件,每次我登录/注销它都会尝试插入或分离它所连接的组件,在这种情况下,因为我导航后该组件将被销毁,所以bug出现了
这是我的指示逻辑:
@Directive({
selector: '[loggedIn]'
})
export class LoggedInDirective implements OnInit, OnDestroy {
private which: boolean = false;
private _loggedIn: boolean = false;
view = this.templateRef.createEmbeddedView(null);
authEventsSub: Subscription;
constructor(
private viewContainerRef: ViewContainerRef,
private templateRef: TemplateRef<any>
) {}
ngOnInit() {
this.authEventsSub = this.authEventsService.events$.subscribe((event: AuthEvent) => {
this._loggedIn = (event === AuthEvent.LOGGED_IN) || (event === AuthEvent.READY);
this.render();
});
}
private render() {
if (this.which) {
if (this._loggedIn) {
this.viewContainerRef.insert(this.view);
} else {
this.viewContainerRef.detach();
}
} else {
if (this._loggedIn) {
this.viewContainerRef.detach();
} else {
this.viewContainerRef.insert(this.view);
}
}
}
// ...
}
通过取消订阅ngOnDestroy
钩子中的observable来修复它:
authEventsSub: Subscription;
constructor(
private viewContainerRef: ViewContainerRef,
private templateRef: TemplateRef<any>,
private authEventsService: AuthEventsService,
) {}
ngOnInit() {
this.authEventsSub = this.authEventsService.events$.subscribe((event: AuthEvent) => {
this._loggedIn = (event === AuthEvent.LOGGED_IN) || (event === AuthEvent.READY);
this.render();
});
}
ngOnDestroy() {
if (this.authEventsSub) {
this.authEventsSub.unsubscribe();
}
}