Merge pull request #5011 from tsiegleauq/NoCdOnDestroy

Fix change detecting dead views
This commit is contained in:
Emanuel Schütze 2019-09-12 16:27:08 +02:00 committed by GitHub
commit 15b90579ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 26 deletions

View File

@ -4,6 +4,7 @@ import {
Component, Component,
EventEmitter, EventEmitter,
Input, Input,
OnDestroy,
OnInit, OnInit,
Output, Output,
ViewChild, ViewChild,
@ -81,7 +82,7 @@ export interface ColumnRestriction {
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel> implements OnInit { export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel> implements OnInit, OnDestroy {
/** /**
* Declare the table * Declare the table
*/ */
@ -243,7 +244,9 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
* @returns the repositories `viewModelListObservable` * @returns the repositories `viewModelListObservable`
*/ */
private get viewModelListObservable(): Observable<V[]> { private get viewModelListObservable(): Observable<V[]> {
return this.repo.getViewModelListObservable(); if (this.repo) {
return this.repo.getViewModelListObservable();
}
} }
/** /**
@ -296,24 +299,27 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
this.dataSource = createDS<V>() this.dataSource = createDS<V>()
.onTrigger(() => { .onTrigger(() => {
let listObservable: Observable<V[]>; let listObservable: Observable<V[]>;
if (this.filterService && this.sortService) { if (this.repo && this.viewModelListObservable) {
// filtering and sorting if (this.filterService && this.sortService) {
this.filterService.initFilters(this.viewModelListObservable); // filtering and sorting
this.sortService.initSorting(this.filterService.outputObservable); this.filterService.initFilters(this.viewModelListObservable);
listObservable = this.sortService.outputObservable; this.sortService.initSorting(this.filterService.outputObservable);
} else if (this.filterService) { listObservable = this.sortService.outputObservable;
// only filter service } else if (this.filterService) {
this.filterService.initFilters(this.viewModelListObservable); // only filter service
listObservable = this.filterService.outputObservable; this.filterService.initFilters(this.viewModelListObservable);
} else if (this.sortService) { listObservable = this.filterService.outputObservable;
// only sorting } else if (this.sortService) {
this.sortService.initSorting(this.viewModelListObservable); // only sorting
listObservable = this.sortService.outputObservable; this.sortService.initSorting(this.viewModelListObservable);
} else { listObservable = this.sortService.outputObservable;
// none of both } else {
listObservable = this.viewModelListObservable; // none of both
listObservable = this.viewModelListObservable;
}
} }
return listObservable;
return listObservable ? listObservable : [];
}) })
.create(); .create();
@ -394,6 +400,13 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
} }
} }
/**
* Stop the change detection
*/
public ngOnDestroy(): void {
this.cd.detach();
}
/** /**
* Receive manual view updates * Receive manual view updates
*/ */

View File

@ -102,6 +102,7 @@ export class MetaTextBlockComponent extends BaseComponent implements OnInit, OnD
this.contentSubscription.unsubscribe(); this.contentSubscription.unsubscribe();
this.contentSubscription = null; this.contentSubscription = null;
} }
this.cd.detach();
} }
/** /**

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { SearchProperty } from 'app/core/ui-services/search.service'; import { SearchProperty } from 'app/core/ui-services/search.service';
@ -11,7 +11,7 @@ import { Searchable } from 'app/site/base/searchable';
styleUrls: ['./preview.component.scss'], styleUrls: ['./preview.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class PreviewComponent { export class PreviewComponent implements OnDestroy {
/** /**
* Sets the view-model, whose properties are displayed. * Sets the view-model, whose properties are displayed.
* *
@ -50,6 +50,13 @@ export class PreviewComponent {
*/ */
public constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {} public constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {}
/**
* detach the change detection
*/
public ngOnDestroy(): void {
this.cd.detach();
}
/** /**
* Function to sanitize any text to show html. * Function to sanitize any text to show html.
* *

View File

@ -125,5 +125,7 @@ export class ProgressSnackBarComponent implements OnInit, OnDestroy {
this.progressModeSubscription.unsubscribe(); this.progressModeSubscription.unsubscribe();
this.progressModeSubscription = null; this.progressModeSubscription = null;
} }
this.cd.detach();
} }
} }

View File

@ -1,7 +1,7 @@
<div class="filter-menu-content-wrapper"> <div class="filter-menu-content-wrapper">
<mat-accordion (keyup)="checkKeyEvent($event)"> <mat-accordion (keyup)="checkKeyEvent($event)">
<mat-expansion-panel *ngFor="let filter of service.filterDefinitions"> <mat-expansion-panel *ngFor="let filter of service.filterDefinitions">
<mat-expansion-panel-header *ngIf="filter.options && filter.options.length"> <mat-expansion-panel-header *ngIf="filter && filter.options && filter.options.length">
<mat-panel-title> <mat-panel-title>
<span>{{ service.getFilterName(filter) | translate }}</span> <span>{{ service.getFilterName(filter) | translate }}</span>
<mat-basic-chip disableRipple class="lightblue filter-count" *ngIf="filter.count"> <mat-basic-chip disableRipple class="lightblue filter-count" *ngIf="filter.count">

View File

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { BaseFilterListService, OsFilterOption } from 'app/core/ui-services/base-filter-list.service'; import { BaseFilterListService, OsFilterOption } from 'app/core/ui-services/base-filter-list.service';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
@ -20,7 +20,7 @@ import { BaseViewModel } from 'app/site/base/base-view-model';
styleUrls: ['./filter-menu.component.scss'], styleUrls: ['./filter-menu.component.scss'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class FilterMenuComponent implements OnInit { export class FilterMenuComponent implements OnInit, OnDestroy {
/** /**
* An event emitter to submit a desire to close this component * An event emitter to submit a desire to close this component
* TODO: Might be an easier way to do this * TODO: Might be an easier way to do this
@ -50,6 +50,13 @@ export class FilterMenuComponent implements OnInit {
} }
} }
/**
*
*/
public ngOnDestroy(): void {
this.dismissed.unsubscribe();
}
/** /**
* Tests for escape key (to colose the sidebar) * Tests for escape key (to colose the sidebar)
* @param event * @param event

View File

@ -75,5 +75,6 @@ export class GlobalSpinnerComponent implements OnInit, OnDestroy {
this.isVisible = false; this.isVisible = false;
} }
this.spinnerSubscription = null; this.spinnerSubscription = null;
this.cd.detach();
} }
} }

View File

@ -1,4 +1,12 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Input,
OnDestroy,
OnInit,
ViewEncapsulation
} from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
@ -28,7 +36,7 @@ import { ViewConfig } from '../../models/view-config';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None // to style the date and time pickers encapsulation: ViewEncapsulation.None // to style the date and time pickers
}) })
export class ConfigFieldComponent extends BaseComponent implements OnInit { export class ConfigFieldComponent extends BaseComponent implements OnInit, OnDestroy {
public configItem: ViewConfig; public configItem: ViewConfig;
/** /**
@ -147,6 +155,13 @@ export class ConfigFieldComponent extends BaseComponent implements OnInit {
}); });
} }
/**
* Stops the change detection
*/
public ngOnDestroy(): void {
this.cd.detach();
}
/** /**
* Helper function to split a unix timestamp into a date as a moment object and a time string in the form of HH:SS * Helper function to split a unix timestamp into a date as a moment object and a time string in the form of HH:SS
* *

View File

@ -243,6 +243,7 @@ export class MediafileListComponent extends BaseListViewComponent<ViewMediafile>
public ngOnDestroy(): void { public ngOnDestroy(): void {
super.ngOnDestroy(); super.ngOnDestroy();
this.clearSubscriptions(); this.clearSubscriptions();
this.cd.detach();
} }
/** /**