Skip to content

Commit

Permalink
Fixed problem with subscriptions when a component is destroyed
Browse files Browse the repository at this point in the history
  • Loading branch information
pIvan committed Oct 22, 2019
1 parent 0cf7021 commit d6b677b
Show file tree
Hide file tree
Showing 18 changed files with 252 additions and 51 deletions.
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
<link rel="stylesheet" href="styles.257d58d4fd6a05e4447e.css"></head>
<body>
<app-root></app-root>
<script src="polyfills-nomodule-es5.b79bfebc521ac1ea1602.js" nomodule></script><script src="polyfills-es5.3aa54d3e5134f5b5b842.js" nomodule defer></script><script src="polyfills-es2015.fd917e7c3ed57f282ee5.js" type="module"></script><script src="runtime-es2015.24b02acc1f369d9b9f37.js" type="module"></script><script src="main-es2015.89c8eade1d837bc89f5d.js" type="module"></script><script src="runtime-es5.24b02acc1f369d9b9f37.js" nomodule defer></script><script src="main-es5.89c8eade1d837bc89f5d.js" nomodule defer></script></body>
<script src="polyfills-nomodule-es5.b79bfebc521ac1ea1602.js" nomodule></script><script src="polyfills-es5.3aa54d3e5134f5b5b842.js" nomodule defer></script><script src="polyfills-es2015.fd917e7c3ed57f282ee5.js" type="module"></script><script src="runtime-es2015.24b02acc1f369d9b9f37.js" type="module"></script><script src="main-es2015.64d81fb91380c0336797.js" type="module"></script><script src="runtime-es5.24b02acc1f369d9b9f37.js" nomodule defer></script><script src="main-es5.64d81fb91380c0336797.js" nomodule defer></script></body>
</html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion projects/iplab/ngx-color-picker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "",
"homepage": "https://github.com/pIvan/ngx-color-picker",
"bugs": "https://github.com/pIvan/ngx-color-picker/issues",
"version": "1.0.4",
"version": "1.0.5",
"author": "Ivan Pintar",
"license": "MIT",
"readmeFilename": "README.md",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `chrome-picker`,
Expand All @@ -37,6 +38,8 @@ export class ChromePickerComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public colorChange: EventEmitter<ColorString> = new EventEmitter(false);

private subscriptions: Array<Subscription> = [];

constructor(private readonly cdr: ChangeDetectorRef) {
}

Expand Down Expand Up @@ -78,15 +81,18 @@ export class ChromePickerComponent implements OnInit, OnChanges, OnDestroy {
]);
}

this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand All @@ -100,4 +106,4 @@ export class ChromePickerComponent implements OnInit, OnChanges, OnDestroy {
this.selectedPresentation === this.presentations.length - 1 ? 0 : this.selectedPresentation + 1;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `compact-picker`,
Expand All @@ -34,6 +35,8 @@ export class CompactPickerComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public colorChange: EventEmitter<ColorString> = new EventEmitter(false);

private subscriptions: Array<Subscription> = [];

constructor(private readonly cdr: ChangeDetectorRef) {
}

Expand All @@ -57,15 +60,18 @@ export class CompactPickerComponent implements OnInit, OnChanges, OnDestroy {
]);
}

this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `github-picker`,
Expand All @@ -34,6 +35,8 @@ export class GithubPickerComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public colorChange: EventEmitter<ColorString> = new EventEmitter(false);

private subscriptions: Array<Subscription> = [];

constructor(private readonly cdr: ChangeDetectorRef) {
}

Expand All @@ -58,15 +61,18 @@ export class GithubPickerComponent implements OnInit, OnChanges, OnDestroy {
]);
}

this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `ip-picker`,
Expand All @@ -33,6 +34,8 @@ export class IpPickerComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public colorChange: EventEmitter<ColorString> = new EventEmitter(false);

private subscriptions: Array<Subscription> = [];

constructor() {
}

Expand Down Expand Up @@ -74,13 +77,16 @@ export class IpPickerComponent implements OnInit, OnChanges, OnDestroy {
this.control.setValueFrom(this.color);
}

this.control.valueChanges.subscribe((value) => {
this.colorChange.emit(getValueByType(value, this.control.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.colorChange.emit(getValueByType(value, this.control.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `sketch-picker`,
Expand All @@ -34,6 +35,8 @@ export class SketchPickerComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public colorChange: EventEmitter<ColorString> = new EventEmitter(false);

private subscriptions: Array<Subscription> = [];

constructor(private readonly cdr: ChangeDetectorRef) {
}

Expand All @@ -58,15 +61,18 @@ export class SketchPickerComponent implements OnInit, OnChanges, OnDestroy {
]);
}

this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(getValueByType(value, this.control.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { ColorString } from './../../helpers/color.class';
import { ColorPickerControl } from './../../helpers/control.class';
import { getValueByType } from './../../helpers/helper.functions';
import { Subscription } from 'rxjs';

@Component({
selector: `swatches-picker`,
Expand All @@ -33,6 +34,7 @@ export class SwatchesPickerComponent implements OnInit, OnChanges, OnDestroy {

public control: ColorPickerControl = new ColorPickerControl();
public childControl: ColorPickerControl = new ColorPickerControl();
private subscriptions: Array<Subscription> = [];

private mapColors = {
'#E6315B': [
Expand Down Expand Up @@ -95,24 +97,28 @@ export class SwatchesPickerComponent implements OnInit, OnChanges, OnDestroy {
*/
this.childControl.setColorPresets(this.mapColors['#E6315B']);

this.childControl.valueChanges.subscribe((value) => {
this.colorChange.emit(getValueByType(value, this.childControl.initType));
});
this.subscriptions.push(
this.childControl.valueChanges.subscribe((value) => {
this.colorChange.emit(getValueByType(value, this.childControl.initType));
})
);

this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
const presets = this.mapColors[value.toHexString()];
if (presets) {
this.childControl.setColorPresets(presets);
}
this.colorChange.emit(getValueByType(this.childControl.value, this.childControl.initType));
});
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
const presets = this.mapColors[value.toHexString()];
if (presets) {
this.childControl.setColorPresets(presets);
}
this.colorChange.emit(getValueByType(this.childControl.value, this.childControl.initType));
})
);
}

public ngOnDestroy(): void {
this.control.unsubscribe();
this.childControl.unsubscribe();
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0;
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,4 @@ export class ColorPickerControl {
this.presetsVisibilityChanges.next(false);
return this;
}

/**
* complete emit on all observers
*/
public unsubscribe(): void {
this.valueChanged.complete();
this.presetsVisibilityChanges.complete();
}
}
70 changes: 70 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,76 @@ <h6>attributes explanation</h6>
</div>
<br>


<div class="card" id="wrap-component">
<div class="card-header">How to wrapp color picker</div>
<div class="card-block">
<div class="row">
<div class="col col-lg-4">

<div class="info-row">
<code>selected color: {{ wrapperColor }}</code><br>
</div>
<chrome-wrapper [(color)]="wrapperColor"></chrome-wrapper>
</div>
<div class="col col-lg-8">
<p>Component code</p>
<pre class="prettify">
@Component(&#123;
...
selector: 'chrome-wrapper',
template: '
&lt;chrome-picker *ngIf="isVisible" [control]="colorControl"&gt;&lt;/chrome-picker&gt;
&lt;div *ngIf="isVisible" class="overlay" (click)="overlayClick($event)"&gt;&lt;/div&gt;
'
&#125;)
export class ChromeWrapperComponent &#123;

public colorControl = new ColorPickerControl();

public isVisible: boolean = false;

@Input()
public set color(color: string) &#123;
this.colorControl.setValueFrom(color);
&#125;

@Output()
public colorChange: EventEmitter&lt;string&gt; = new EventEmitter();

@HostBinding('style.background-color')
public get background(): string &#123;
return this.colorControl.value.toHexString();
&#125;

public ngOnInit() &#123;
this.colorControl.valueChanges.subscribe((value: Color) => this.colorChange.emit(value.toHexString()));
&#125;

@HostListener('click', ['$event'])
public showColorPicker(event: MouseEvent) &#123;
if (this.isVisible === true) &#123;
return;
&#125;

this.isVisible = !this.isVisible;
&#125;

public overlayClick(event: MouseEvent): void &#123;
event.preventDefault();
event.stopPropagation();
this.isVisible = false;
&#125;
&#125;</pre>

<p>Use case</p>
<pre class="prettify">&lt;chrome-wrapper [(color)]="wrapperColor"&gt;&lt;/chrome-wrapper&gt;</pre>
</div>
</div>
</div>
</div>
<br>

<div class="card">
<div class="card-header">ColorPickerControl methods</div>
<div class="card-block">
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class AppComponent {
.setValueFrom('#1273DE');

public swatchesColor = '#F04A71';

public wrapperColor = '#F04A71';

constructor(private readonly elRef: ElementRef) {
}
Expand Down
Loading

0 comments on commit d6b677b

Please sign in to comment.