直到最近我们使用express.js为Angular提供index.html,因为我们需要在应用程序启动之前从数据库中填充动态变量。
<script> window .__ envs = {{{json envs}}} </script>
但是,新的Angular 7通过web-worker缓存源index.html。
因此,当我加载网页时,在我点击重新加载之前它无法正常加载。
我试图从webworker中禁用index.html。没啥事儿。
我试图关闭网络工作者并将其删除。现在我不必使用硬重载,但仍然第一次加载将显示源文件而不是通过express.js修改
1)为什么源加载源文件以及它是如何获取的?
2)我可以在网络工作者中设置它吗?
您可以在模块中使用APP_INITIALIZER并使用工厂加载提供程序服务,如下所示:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule
],
providers: [
ServiceProvider,
{ provide: APP_INITIALIZER, useFactory: ServiceProviderFactory, deps: [ServiceProvider], multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
您的服务以获取数据作为服务:
@Injectable()
export class ServiceProvider{
constructor(private http: Http) {
}
getInitialData(){
// your fetch logic from API
}
}
您的服务工厂(添加模块):
export function ServiceProviderFactory(provider: ServiceProvider) {
return () => provider.getInitialData();
}
刷新两次后,索引文件将更新是正常的。
服务工作者实现的缓存机制将检查哈希值以检测文件的任何更改。如果哈希值不同,则下载新版本并对其进行缓存(但不会从第一次开始显示)。
第二次刷新后,您将看到更新的版本。
如果您根本不需要缓存,可以从angular.json中禁用服务工作者:
"configurations": {
"production": {
"serviceWorker": false,
"ngswConfigPath": "src/ngsw-config.json"
}
}
此外,您可以侦听更改(SW工作程序检测到何时找到新版本)并使用按钮刷新页面向用户显示正确的消息。看看here如何捕获和处理更新过程。
祝好运!
谢谢你的答案,但没有人可以完全解决我的问题。我不能使用APP_INITIALIZER
,因为我现在不知道API_URL
,这是我需要传递给应用程序的东西之一。它是动态值,所以它不能成为process.env
的一部分。
禁用缓存index.html对我来说无法正常工作。
但解决方案非常简单。
我没有直接更改index.html文件,而是将<script src="/envs">
放入其中,并将此文件暴露在express.js中
app.get('/envs', async (req, res) => {
const envs = ...
res.end('window.__envs = ' + JSON.stringify(envs))
})