Angular index.html 具有动态值 |网络工作者
Angular index.html with dynamic values | web-worker
直到最近我们使用 express.js 为 Angular 服务 index.html,因为我们需要在应用程序启动之前从数据库中填充动态变量。
<script> window .__ envs = {{{json envs}}} </script>
但是,新的 Angular 7 通过 web-worker 缓存源 index.html。
所以当我加载网络时,它不会正确加载,直到我点击重新加载。
我试图从 webworker 中禁用 index.html。什么都没发生。
我试图关闭 web-worker 并在所有地方删除它。现在我不必使用硬重新加载,但第一次加载仍然会显示源文件而不是通过 express.js
修改的
1) 源为什么要加载源文件,它是如何到达的?
2) 我可以在 webworker 中设置它吗?
您可以在模块中使用 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();
}
您的 index 文件刷新两次后会更新是正常的。
Service Worker 实现的缓存机制将检查哈希和以检测文件的任何更改。如果哈希值不同,将下载新版本并缓存它(但不会从第一次显示)。
第二次刷新后,您将看到更新后的版本。
如果你根本不需要缓存,你可以从 angular.json:
"configurations": {
"production": {
"serviceWorker": false,
"ngswConfigPath": "src/ngsw-config.json"
}
}
此外,您还可以侦听更改(SW worker 会检测何时发现新版本)并使用刷新页面的按钮向用户显示适当的消息。看看 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))
})
直到最近我们使用 express.js 为 Angular 服务 index.html,因为我们需要在应用程序启动之前从数据库中填充动态变量。
<script> window .__ envs = {{{json envs}}} </script>
但是,新的 Angular 7 通过 web-worker 缓存源 index.html。
所以当我加载网络时,它不会正确加载,直到我点击重新加载。
我试图从 webworker 中禁用 index.html。什么都没发生。
我试图关闭 web-worker 并在所有地方删除它。现在我不必使用硬重新加载,但第一次加载仍然会显示源文件而不是通过 express.js
修改的1) 源为什么要加载源文件,它是如何到达的?
2) 我可以在 webworker 中设置它吗?
您可以在模块中使用 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();
}
您的 index 文件刷新两次后会更新是正常的。
Service Worker 实现的缓存机制将检查哈希和以检测文件的任何更改。如果哈希值不同,将下载新版本并缓存它(但不会从第一次显示)。
第二次刷新后,您将看到更新后的版本。
如果你根本不需要缓存,你可以从 angular.json:
"configurations": {
"production": {
"serviceWorker": false,
"ngswConfigPath": "src/ngsw-config.json"
}
}
此外,您还可以侦听更改(SW worker 会检测何时发现新版本)并使用刷新页面的按钮向用户显示适当的消息。看看 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))
})