From 86d55f6367a7669c413c7c56eca3439332891c86 Mon Sep 17 00:00:00 2001
From: Rob McDiarmid <rmcdiarmid@konradgroup.com>
Date: Fri, 19 May 2017 16:49:32 -0400
Subject: [PATCH] added cache for view refs

---
 CHANGELOG.md                |  6 +++++-
 dist/lazyFor.directive.d.ts |  1 +
 dist/lazyFor.directive.js   | 25 ++++++++++++++++++++-----
 src/lazyFor.directive.ts    | 23 ++++++++++++++++++-----
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53fef54..2c113c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
 # Change Log
 
+## [1.1.4] - 2017-04-24
+
 ## 1.1.3 - 2017-04-24
 - Added check to only regenerate DOM elements if items in the list have changed or a scroll event has fired. This greatly improves performance in some cases.
 - Added this change log
@@ -20,4 +22,6 @@
 
 ## 1.0.0 - 2017-04-19
 - Initial release
-- Added all the things
\ No newline at end of file
+- Added all the things
+
+[1.1.4]: https://github.com/robianmcd/angular-lazy-for/compare/v1.1.3...v1.1.4
\ No newline at end of file
diff --git a/dist/lazyFor.directive.d.ts b/dist/lazyFor.directive.d.ts
index 2ca7e35..4e2d517 100644
--- a/dist/lazyFor.directive.d.ts
+++ b/dist/lazyFor.directive.d.ts
@@ -15,6 +15,7 @@ export declare class LazyForDirective implements DoCheck {
     private firstUpdate;
     private differ;
     private lastChangeTriggeredByScroll;
+    private viewRefCache;
     constructor(vcr: ViewContainerRef, tpl: TemplateRef<any>, iterableDiffers: IterableDiffers);
     ngOnInit(): void;
     ngDoCheck(): void;
diff --git a/dist/lazyFor.directive.js b/dist/lazyFor.directive.js
index 4aaca28..621f22f 100644
--- a/dist/lazyFor.directive.js
+++ b/dist/lazyFor.directive.js
@@ -8,6 +8,7 @@ var LazyForDirective = (function () {
         this.initialized = false;
         this.firstUpdate = true;
         this.lastChangeTriggeredByScroll = false;
+        this.viewRefCache = [];
     }
     Object.defineProperty(LazyForDirective.prototype, "lazyForOf", {
         set: function (list) {
@@ -66,16 +67,30 @@ var LazyForDirective = (function () {
         var fixedHeaderHeight = (this.beforeListElem.getBoundingClientRect().top - this.beforeListElem.scrollTop) -
             (this.containerElem.getBoundingClientRect().top - this.containerElem.scrollTop);
         //This needs to run after the scrollTop is retrieved.
-        this.vcr.clear();
+        //If the list changed then get rid of the viewRefCache
+        if (!this.lastChangeTriggeredByScroll) {
+            this.vcr.clear();
+            this.viewRefCache = [];
+        }
+        else {
+            for (var i = this.vcr.length - 1; i <= 0; i--) {
+                this.vcr.detach(i);
+            }
+        }
         var listStartI = Math.floor((scrollTop - fixedHeaderHeight) / this.itemHeight);
         listStartI = this.limitToRange(listStartI, 0, this.list.length);
         var listEndI = Math.ceil((scrollTop - fixedHeaderHeight + listHeight) / this.itemHeight);
         listEndI = this.limitToRange(listEndI, -1, this.list.length - 1);
         for (var i = listStartI; i <= listEndI; i++) {
-            this.vcr.createEmbeddedView(this.tpl, {
-                $implicit: this.list[i],
-                index: i
-            });
+            if (this.viewRefCache[i]) {
+                this.vcr.insert(this.viewRefCache[i]);
+            }
+            else {
+                this.viewRefCache[i] = this.vcr.createEmbeddedView(this.tpl, {
+                    $implicit: this.list[i],
+                    index: i
+                });
+            }
         }
         this.beforeListElem.style.height = listStartI * this.itemHeight + "px";
         this.afterListElem.style.height = (this.list.length - listEndI - 1) * this.itemHeight + "px";
diff --git a/src/lazyFor.directive.ts b/src/lazyFor.directive.ts
index aa4b5c5..c8cc2a5 100644
--- a/src/lazyFor.directive.ts
+++ b/src/lazyFor.directive.ts
@@ -36,6 +36,7 @@ export class LazyForDirective implements DoCheck {
     private differ: IterableDiffer<any>;
 
     private lastChangeTriggeredByScroll = false;
+    private viewRefCache = [];
 
     constructor(
         private vcr: ViewContainerRef,
@@ -100,7 +101,15 @@ export class LazyForDirective implements DoCheck {
             (this.containerElem.getBoundingClientRect().top - this.containerElem.scrollTop);
 
         //This needs to run after the scrollTop is retrieved.
-        this.vcr.clear();
+        //If the list changed then get rid of the viewRefCache
+        if(!this.lastChangeTriggeredByScroll) {
+            this.vcr.clear();
+            this.viewRefCache = [];
+        } else {
+            for (let i = this.vcr.length-1; i <= 0; i--) {
+                this.vcr.detach(i);
+            }
+        }
 
         let listStartI = Math.floor((scrollTop - fixedHeaderHeight) / this.itemHeight);
         listStartI = this.limitToRange(listStartI, 0, this.list.length);
@@ -109,10 +118,14 @@ export class LazyForDirective implements DoCheck {
         listEndI = this.limitToRange(listEndI, -1, this.list.length - 1);
 
         for (let i = listStartI; i <= listEndI; i++) {
-            this.vcr.createEmbeddedView(this.tpl, {
-                $implicit: this.list[i],
-                index: i
-            });
+            if(this.viewRefCache[i]) {
+                this.vcr.insert(this.viewRefCache[i]);
+            } else {
+                this.viewRefCache[i] = this.vcr.createEmbeddedView(this.tpl, {
+                    $implicit: this.list[i],
+                    index: i
+                });
+            }
         }
 
         this.beforeListElem.style.height = `${listStartI * this.itemHeight}px`;