umijs / qiankun

📦 🚀 Blazing fast, simple and complete solution for micro frontends.
https://qiankun.umijs.org
MIT License
15.83k stars 2.02k forks source link

以Angular9为基座的应用,在浏览器回退后视图无法正常显示 #1450

Closed Sh-Zh-7 closed 3 years ago

Sh-Zh-7 commented 3 years ago

What happens?

我用Angular9为基座框架,vue2为微应用框架写了一个简易的前端。 功能是在angular9视图中提交表单后,自动跳转到vue2的视图。借助官网提供的教程这个功能确实能正常运作。 但是当我在vue2视图中按下浏览器回退按钮之后,angular9视图中的表单就无法正常显示了,经过调试,发现Angular路由在跳转过后甚至没有调用ngOnInit方法。 我偶然按下F12的按钮,这个表单就能正常显示了。不过,如果此时按下表单按钮跳转回vue视图,那么angular和视图和vue的视图甚至会出现在同一页面! 起初我以为是angular-router的问题,但是当我在主应用把所有qiankun的代码注释(如registerMicroApps等)后,这个应用又能正常运行(回退能正常显示表单,再次跳转也不会出现多个视图出现在同一页面)。 我怀疑是angular-router和qiankun有冲突,因此希望得到一个解决方案。

最小可复现仓库

https://github.com/students-hub/StudentsHub-Frontend

复现步骤,错误日志以及相关配置

  1. 进入这个网址
  2. 按下登录按钮进入vue视图,点击浏览器回退,发现表单显示不完全。
  3. 按F12,发现表单又能显示完全了。
  4. 继续按下登录,发现vue视图和angular视图出现在同一页面。

相关环境信息

Sh-Zh-7 commented 3 years ago

换了个方法,注入NgZone实例+手动加载子应用解决了。

Whilconn commented 3 years ago

碰到同样的问题,主应用是angular10,子应用是angular6,经过调试分析已解决。

1、问题原因

zonejs没有按正常逻辑运行,导致routerjs中的一段setTimeout代码运行在ngzone之外,变更检测失败了。

2、调试大体步骤

图1 image

图2 image

图3 image

3、解决方案:

• 方案1:在子应用的入口组件app.component.ts中定时运行zone.run。方法很low但能解决问题。代码如下:

// app.component.ts -> AppComponent -> ngOnInit

setInterval(() => {
  this.zone.run(() => {});
}, 1000);

• 方案2(推荐):在子应用的入口组件app.component.ts中监听popstate事件再运行zone.run。方法很low但能解决问题,另外比上一个好点。代码如下:

// app.component.ts -> AppComponent -> ngOnInit

window.addEventListener('popstate', () => {
  setTimeout(() => this.zone.run(() => {}), 100);
});