Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IE not calling lifecycle hooks or filling @Input until change detected?

I'm using beta.0 because this outstanding bug prevents angular 2 from working in IE in beta.1 and beta.2.

Relevant code from SearchBar.ts

@Component({
  selector : 'search-bar',
  templateUrl: 'views/searchbar.html'
})
export class SearchBar {
  private history: SearchHistoryEntry[] = [];

  @Output() onHistory = new EventEmitter();

  constructor() {
    this.history = JSON.parse(localStorage.getItem('SearchHistory')) || [];
  }

  ngOnInit() {
    // The constructor doesn't have @Outputs initialized yet. Emit from this
    // life cycle hook instead to be sure they're received on the other side
    debugger;
    this.onHistory.emit(this.history);
  }
}

Relevant code from home.html

<search-bar (onHistory)="SearchBarHistory($event)"></search-bar>

Relevant code from home.ts

SearchBarHistory(history: SearchHistoryEntry[]) {
  debugger;
  this.history = history;
}

In Chrome this works just fine. The SearchBar's constructor correctly reads from localStorage, in ngOnInit it emits to my Home component who receives it, it's stored locally and the UI bindings tied to history update to show the information as it all should.

In IE 11 this does not work. ngOnInit won't run until I click inside my search bar. It seems that any @Input or lifecycle hook (specifically I've tested ngOnInit, ngAfterContentInit, and ngAfterViewInit and they all behave the same) doesn't run until the component's change detection is triggered. If I refresh the page then it runs exactly like Chrome where no interaction is required for @Inputs or lifecycle hooks to be called and my history goes through and gets bound like it should.

I think this is a bug of the beta but in the mean time is there anything I can do to make it work the first time without an interaction or page refresh?

like image 415
Corey Ogburn Avatar asked Oct 31 '22 10:10

Corey Ogburn


1 Answers

I am having the same issue I tried it to resolve by forcing detectChanges like:

import {Injectable,ApplicationRef, NgZone} from '@angular/core';
@Injectable()
export class IeHackService {

constructor(
    private _appRef: ApplicationRef,
    private _zone: NgZone) {}

private isIe() {
    let ua = window.navigator.userAgent;
    let msie = ua.indexOf('MSIE ');
    if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number
        return true;
    return false;
}

onComponentLoadInIe() {
    if (this.isIe()) {
        this._zone.run(() => setTimeout(() => this._appRef.tick(), 5));
    }
}
}

Then in Every Route component that uses Lifecycle Hooks I called

   constructor(private dialogService: ModalDialogService,ieHackService: IeHackService) {
    ieHackService.onComponentLoadInIe();
}
like image 167
yo chauhan Avatar answered Nov 09 '22 12:11

yo chauhan