Skip to content

Commit 6319e33

Browse files
Merge pull request #9 from edusperoni/loaded-fix
increase ListView compatibility
2 parents a805380 + 15d2c78 commit 6319e33

File tree

1 file changed

+50
-16
lines changed

1 file changed

+50
-16
lines changed

lib/src/nativescript-ngx-shadow/ng-shadow.directive.ts

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
OnInit,
88
SimpleChanges,
99
Renderer2,
10-
AfterViewInit
10+
AfterViewInit,
11+
OnDestroy
1112
} from '@angular/core';
1213
import { isAndroid, isIOS } from 'tns-core-modules/platform';
1314

@@ -17,10 +18,11 @@ import { Shadow } from './common/shadow';
1718
import { Shape, ShapeEnum } from './common/shape.enum';
1819
import { View } from 'tns-core-modules/ui/page/page';
1920
import { StackLayout } from 'tns-core-modules/ui/layouts/stack-layout';
21+
import { addWeakEventListener, removeWeakEventListener } from "tns-core-modules/ui/core/weak-event-listener";
2022
declare const android: any;
2123

2224
@Directive({ selector: '[shadow]' })
23-
export class NativeShadowDirective implements OnInit, OnChanges, AfterViewInit {
25+
export class NativeShadowDirective implements OnInit, OnChanges, AfterViewInit, OnDestroy {
2426
@Input() shadow: string | AndroidData | IOSData;
2527
@Input() elevation?: number | string;
2628
@Input() pressedElevation?: number | string;
@@ -43,32 +45,65 @@ export class NativeShadowDirective implements OnInit, OnChanges, AfterViewInit {
4345
private originalNSFn: any;
4446
private previousNSFn: any;
4547
private iosShadowRapper: View;
48+
private eventsBound = false;
4649

4750
constructor(private el: ElementRef, private render: Renderer2) {
4851
if (isAndroid) {
4952
this.originalNSFn = this.el.nativeElement._redrawNativeBackground; //always store the original method
5053
}
5154
}
5255

53-
ngOnInit() {
54-
this.initializeCommonData();
55-
if (isAndroid) {
56-
this.initializeAndroidData();
57-
} else if (isIOS) {
58-
this.initializeIOSData();
59-
}
60-
if (this.shadow && (this.shadow as AndroidData | IOSData).elevation) {
56+
ngOnInit() { // RadListView calls this multiple times for the same view
57+
if (!this.initialized) {
58+
this.initialized = true;
59+
this.initializeCommonData();
6160
if (isAndroid) {
62-
this.loadFromAndroidData(this.shadow as AndroidData);
61+
this.initializeAndroidData();
6362
} else if (isIOS) {
64-
this.loadFromIOSData(this.shadow as IOSData);
63+
this.initializeIOSData();
64+
}
65+
if (this.shadow && (this.shadow as AndroidData | IOSData).elevation) {
66+
if (isAndroid) {
67+
this.loadFromAndroidData(this.shadow as AndroidData);
68+
} else if (isIOS) {
69+
this.loadFromIOSData(this.shadow as IOSData);
70+
}
6571
}
72+
this.bindEvents();
73+
}
74+
}
75+
76+
ngOnDestroy() {
77+
if (this.initialized) {
78+
this.unbindEvents();
79+
this.initialized = false;
80+
}
81+
}
82+
83+
// NS ListViews create elements dynamically
84+
// loaded and unloaded are called before angular is "ready"
85+
// https://github.com/NativeScript/nativescript-angular/issues/1221#issuecomment-422813111
86+
// So we ensure we're running loaded/unloaded events outside of angular
87+
bindEvents() {
88+
if (!this.eventsBound) {
89+
addWeakEventListener(this.el.nativeElement, View.loadedEvent, this.onLoaded, this);
90+
addWeakEventListener(this.el.nativeElement, View.unloadedEvent, this.onUnloaded, this);
91+
this.eventsBound = true;
92+
// in some cases, the element is already loaded by time of binding
93+
if (this.el.nativeElement.isLoaded) {
94+
this.onLoaded();
95+
}
96+
}
97+
}
98+
99+
unbindEvents() {
100+
if (this.eventsBound) {
101+
removeWeakEventListener(this.el.nativeElement, View.loadedEvent, this.onLoaded, this);
102+
removeWeakEventListener(this.el.nativeElement, View.unloadedEvent, this.onUnloaded, this);
103+
this.eventsBound = false;
66104
}
67-
this.applyShadow();
68-
this.initialized = true;
69105
}
70106

71-
@HostListener('loaded')
72107
onLoaded() {
73108
this.loaded = true;
74109
// Weirdly ngOnInit isn't called on iOS on demo app
@@ -104,7 +139,6 @@ export class NativeShadowDirective implements OnInit, OnChanges, AfterViewInit {
104139
}
105140
}
106141

107-
@HostListener('unloaded')
108142
onUnloaded() {
109143
this.loaded = false;
110144

0 commit comments

Comments
 (0)