IE没有调用生命周期钩子或填充@Input直到检测到更改?

时间:2016-02-02 17:19:11

标签: internet-explorer-11 angular

我正在使用beta.0,因为this outstanding bug阻止了角度2在beta.1和beta.2中的IE中工作。

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);
  }
}

home.html的相关代码

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

home.ts的相关代码

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

在Chrome中,这很好用。 SearchBar的构造函数正确地从localStorage读取,在ngOnInit中它发送到接收它的我的Home组件,它存储在本地,并且绑定到history的UI绑定更新以显示所有信息应该。

在IE 11中,这不起作用。在我点击搜索栏之前,ngOnInit才会运行。似乎任何@Input或生命周期钩子(特别是我已经测试过ngOnInitngAfterContentInitngAfterViewInit并且它们都表现相同)直到组件的运行才会运行触发更改检测。如果我刷新页面,那么它的运行方式与Chrome完全相同,因为@Input或生命周期挂钩不需要进行交互,我的历史记录会经历并受到限制。

我认为这是测试版的一个错误但同时我还能做些什么才能让它在没有交互或页面刷新的情况下第一次工作?

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,我试图通过强制执行detectChanges来解决这个问题:

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));
    }
}
}

然后在使用Lifecycle Hooks的Every Route组件中,我调用了

   constructor(private dialogService: ModalDialogService,ieHackService: IeHackService) {
    ieHackService.onComponentLoadInIe();
}

答案 1 :(得分:0)

我也有这个问题,如果发生错误,我使用了一种解决方法来自动刷新页面,希望the bug最终能够得到解决。

它非常丑陋,但现在它至少起作用了。

declare var Modernizr: any;

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

  @Output() onHistory = new EventEmitter();

  ie11hack: boolean = true;

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

    if (!Modernizr.es6collections || navigator.userAgent.toLowerCase().indexOf("safari") !== -1) {

      setTimeout(() => {
        if (this.ie11hack) {
          window.location.reload();
        }
      }, 500);
    }
  }

  ngOnInit() {
    ie11hack = false;
    // 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);
  }
}

编辑,一个不那么难看的部分修复:

问题是(我认为)是由使用直接网址而不是使用角度路由器(javascript)引起的。 如果你想让你的网站工作,如果人们手动输入他们的网址,那么你仍然需要上面的黑客,但否则你可能会做我在下面做的事情(你可能想要这样做)。

我改变了这个:

<!-- html -->
<a href="#/objects/objectthingy/{{myObject.id}}" class="my-object-class">

对此:

<!-- html -->
<a href="javascript:void(0)" (click)="openMyObject(myObject.id)" class="my-object-class">

// typescript
openMyObject(objectId: number) {
    this.router.navigate(['/Objects', 'ObjectThingy', { id: objectId}]);
}
再次调用

ngAfterViewInit方法。