<commit_before>import {Directive, EmbeddedViewRef, Input, OnChanges, ChangeDetectorRef,
     SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef, NgModule, NgZone, ViewRef, Output, EventEmitter} from '@angular/core';

import { CommonModule } from '@angular/common';

@Directive({selector: '[igxTemplateOutlet]'})
export class IgxTemplateOutletDirective implements OnChanges {
  private _viewRef !: EmbeddedViewRef<any>;
  private _embeddedViewsMap: Map<string, EmbeddedViewRef<any>> = new Map();

  @Input() public igxTemplateOutletContext !: Object;

  @Input() public igxTemplateOutlet !: TemplateRef<any>;


  constructor(private _viewContainerRef: ViewContainerRef,  private _zone: NgZone,  public cdr: ChangeDetectorRef) {
  }

  ngOnChanges(changes: SimpleChanges) {
    const recreateView = this._shouldRecreateView(changes);
    if (recreateView) {
      if (!this._viewRef) {
        // first time - create embedded view.
        this._recreateView();
      } else {
        if (this.igxTemplateOutletContext['templateID']) {
            const res = this._embeddedViewsMap.get(this.igxTemplateOutletContext['templateID']);
            if (res) {
                // use from cache
                const vr = this._viewRef;
                const detachedView = this._viewContainerRef.detach(this._viewContainerRef.indexOf(this._viewRef));
                this._viewRef = res;
                this._viewContainerRef.insert(this._viewRef, 0);
                this._updateExistingContext(this.igxTemplateOutletContext);
            } else {
                this._recreateView();
            }
        } else {
            this._recreateView();
        }
     }
    } else {
      if (this._viewRef && this.igxTemplateOutletContext) {
          this._updateExistingContext(this.igxTemplateOutletContext);
      }
    }
  }

  private _recreateView() {
     // remove and recreate
     if (this._viewRef) {
         this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
      }
      if (this.igxTemplateOutlet) {
        this._viewRef = this._viewContainerRef.createEmbeddedView(
              this.igxTemplateOutlet, this.igxTemplateOutletContext);
            const tmplId = this.igxTemplateOutletContext['templateID'];
            if (tmplId) {<commit_msg>chore(*): Updating ngOnChanges with simpler to follow code and adding comments.<commit_after>import {Directive, EmbeddedViewRef, Input, OnChanges, ChangeDetectorRef,
     SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef, NgModule, NgZone, ViewRef, Output, EventEmitter} from '@angular/core';

import { CommonModule } from '@angular/common';

@Directive({selector: '[igxTemplateOutlet]'})
export class IgxTemplateOutletDirective implements OnChanges {
  private _viewRef !: EmbeddedViewRef<any>;

    /**
    * The embedded views cache. Collection is key-value paired.
    * Key is the template id, value is the embedded view for the related template.
    */
  private _embeddedViewsMap: Map<string, EmbeddedViewRef<any>> = new Map();

  @Input() public igxTemplateOutletContext !: Object;

  @Input() public igxTemplateOutlet !: TemplateRef<any>;


  constructor(private _viewContainerRef: ViewContainerRef,  private _zone: NgZone,  public cdr: ChangeDetectorRef) {
  }

  ngOnChanges(changes: SimpleChanges) {
    const recreateView = this._shouldRecreateView(changes);
    if (recreateView) {
        // view should be re-created due to changes in the template or context.
        // check if we have existing view with the new template stored in the cache.
        const tmplID = this.igxTemplateOutletContext['templateID'];
        const cachedView = tmplID ?
            this._embeddedViewsMap.get(tmplID) :
            null;
        if (!this._viewRef || !cachedView) {
            // if view does not exist yet
            // or if there is no template defined in the template outlet context
            // or if there's no such view in the cache - then re-create view.
            this._recreateView();
        } else {
           // if view exists, but template has been changed and there is a view in the cache with the related template
           // then detach old view and insert the stored one with the matching template
           // after that update its context.
            this._viewContainerRef.detach(this._viewContainerRef.indexOf(this._viewRef));
            this._viewRef = cachedView;
            this._viewContainerRef.insert(this._viewRef, 0);
            this._updateExistingContext(this.igxTemplateOutletContext);
        }
    } else {
        // view should not be re-created. Check if it exists and if context exists and just update it.
      if (this._viewRef && this.igxTemplateOutletContext) {
          this._updateExistingContext(this.igxTemplateOutletContext);
      }
    }
  }

  private _recreateView() {
     // remove and recreate
     if (this._viewRef) {
         this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
      }
      if (this.igxTemplateOutlet) {
        this._viewRef = this._viewContainerRef.createEmbeddedView(
              this.igxTemplateOutlet, this.igxTemplateOutletContext);
            const tmplId = this.igxTemplateOutletContext['templateID'];
            if (tmplId) {
                // if context contains a template id, check if we have a view for that template already stored in the cache
                // if not create a copy and add it to the cache in detached state.
                // Note: Views in detached state do not appear in the DOM, however they remain stored in memory.
{'fraction_non_alphanumeric': 0.08947745168217609, 'fraction_numerical': 0.00035790980672870435, 'mean_word_length': 2.8491735537190084, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '684235', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1495, 'n_words': 417}